Win64 - Allow returning two values from a runtime function.

(Not yet fully functional)

Review URL: http://codereview.chromium.org/201042


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2845 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
lrn@chromium.org 2009-09-08 11:52:05 +00:00
parent ae062d5df1
commit 8f60f1a46f
23 changed files with 398 additions and 317 deletions

View File

@ -5623,7 +5623,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
// argument, so give it a Smi.
__ mov(r0, Operand(Smi::FromInt(0)));
__ push(r0);
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
__ StubReturn(1);
}
@ -5678,6 +5678,13 @@ void UnarySubStub::Generate(MacroAssembler* masm) {
}
int CEntryStub::MinorKey() {
ASSERT(result_size_ <= 2);
// Result returned in r0 or r0+r1 by default.
return 0;
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
// r0 holds the exception.
@ -6195,7 +6202,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
// by calling the runtime system.
__ bind(&slow);
__ push(r1);
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
}
@ -6216,7 +6223,7 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
// Do the runtime call to allocate the arguments object.
__ bind(&runtime);
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
}

View File

@ -391,7 +391,7 @@ void CallIC::Generate(MacroAssembler* masm,
__ mov(r0, Operand(2));
__ mov(r1, Operand(f));
CEntryStub stub;
CEntryStub stub(1);
__ CallStub(&stub);
// Move result to r1 and leave the internal frame.
@ -503,7 +503,7 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
__ stm(db_w, sp, r2.bit() | r3.bit());
// Perform tail call to the entry.
__ TailCallRuntime(f, 2);
__ TailCallRuntime(f, 2, 1);
}
@ -543,7 +543,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
__ ldm(ia, sp, r2.bit() | r3.bit());
__ stm(db_w, sp, r2.bit() | r3.bit());
__ TailCallRuntime(f, 2);
__ TailCallRuntime(f, 2, 1);
}
@ -599,7 +599,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ ldm(ia, sp, r0.bit() | r1.bit());
__ stm(db_w, sp, r0.bit() | r1.bit());
// Do tail-call to runtime routine.
__ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2);
__ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2, 1);
// Fast case: Do the load.
__ bind(&fast);
@ -626,7 +626,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm,
__ ldm(ia, sp, r2.bit() | r3.bit());
__ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
__ TailCallRuntime(f, 3);
__ TailCallRuntime(f, 3, 1);
}
@ -684,7 +684,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
__ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object
__ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
// Do tail-call to runtime routine.
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
// Extra capacity case: Check if there is extra capacity to
// perform the store and update the length. Used for adding one
@ -761,7 +761,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
// Perform tail call to the entry.
__ TailCallRuntime(
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
}
@ -798,7 +798,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
// Perform tail call to the entry.
__ TailCallRuntime(
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
}
@ -814,7 +814,7 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
__ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
// Perform tail call to the entry.
__ TailCallRuntime(f, 3);
__ TailCallRuntime(f, 3, 1);
}

View File

@ -999,7 +999,8 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
int num_arguments) {
int num_arguments,
int result_size) {
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
// should remove this need and make the runtime routine entry code
@ -1015,7 +1016,7 @@ void MacroAssembler::JumpToBuiltin(const ExternalReference& builtin) {
ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
#endif
mov(r1, Operand(builtin));
CEntryStub stub;
CEntryStub stub(1);
Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}

View File

@ -259,7 +259,9 @@ class MacroAssembler: public Assembler {
// Tail call of a runtime routine (jump).
// Like JumpToBuiltin, but also takes care of passing the number
// of parameters.
void TailCallRuntime(const ExternalReference& ext, int num_arguments);
void TailCallRuntime(const ExternalReference& ext,
int num_arguments,
int result_size);
// Jump to the builtin routine.
void JumpToBuiltin(const ExternalReference& builtin);

View File

@ -478,7 +478,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
// Do tail-call to the runtime system.
ExternalReference load_callback_property =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
__ TailCallRuntime(load_callback_property, 5);
__ TailCallRuntime(load_callback_property, 5, 1);
}
@ -514,7 +514,7 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
// Do tail-call to the runtime system.
ExternalReference load_ic_property =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
__ TailCallRuntime(load_ic_property, 5);
__ TailCallRuntime(load_ic_property, 5, 1);
}
@ -884,7 +884,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
// Do tail-call to the runtime system.
ExternalReference store_callback_property =
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
__ TailCallRuntime(store_callback_property, 4);
__ TailCallRuntime(store_callback_property, 4, 1);
// Handle store cache miss.
__ bind(&miss);
@ -936,7 +936,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
// Do tail-call to the runtime system.
ExternalReference store_ic_property =
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
__ TailCallRuntime(store_ic_property, 3);
__ TailCallRuntime(store_ic_property, 3, 1);
// Handle store cache miss.
__ bind(&miss);

View File

@ -517,7 +517,10 @@ const char* RuntimeStub::GetName() {
void RuntimeStub::Generate(MacroAssembler* masm) {
masm->TailCallRuntime(ExternalReference(id_), num_arguments_);
Runtime::Function* f = Runtime::FunctionForId(id_);
masm->TailCallRuntime(ExternalReference(f),
num_arguments_,
f->result_size);
}

View File

@ -286,7 +286,7 @@ class CompareStub: public CodeStub {
class CEntryStub : public CodeStub {
public:
CEntryStub() { }
explicit CEntryStub(int result_size) : result_size_(result_size) { }
void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
@ -302,10 +302,14 @@ class CEntryStub : public CodeStub {
void GenerateThrowTOS(MacroAssembler* masm);
void GenerateThrowUncatchable(MacroAssembler* masm,
UncatchableExceptionType type);
private:
// Number of pointers/values returned.
int result_size_;
Major MajorKey() { return CEntry; }
int MinorKey() { return 0; }
// Minor key must differ if different result_size_ values means different
// code is generated.
int MinorKey();
const char* GetName() { return "CEntryStub"; }
};
@ -313,7 +317,7 @@ class CEntryStub : public CodeStub {
class CEntryDebugBreakStub : public CEntryStub {
public:
CEntryDebugBreakStub() { }
CEntryDebugBreakStub() : CEntryStub(1) { }
void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }

View File

@ -1319,7 +1319,7 @@ bool Heap::CreateApiObjects() {
void Heap::CreateCEntryStub() {
CEntryStub stub;
CEntryStub stub(1);
set_c_entry_code(*stub.GetCode());
}

View File

@ -6886,7 +6886,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
__ j(above_equal, &string1);
// First and second argument are strings.
__ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2);
__ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
// Only first argument is a string.
__ bind(&string1);
@ -7175,7 +7175,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
__ pop(ebx); // Return address.
__ push(edx);
__ push(ebx);
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
}
@ -7200,7 +7200,7 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
// Do the runtime call to allocate the arguments object.
__ bind(&runtime);
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
}
@ -7436,7 +7436,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
__ push(eax);
// Do tail-call to runtime routine.
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
}
@ -7468,6 +7468,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
}
int CEntryStub::MinorKey() {
ASSERT(result_size_ <= 2);
// Result returned in eax, or eax+edx if result_size_ is 2.
return 0;
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
// eax holds the exception.

View File

@ -404,7 +404,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
__ push(eax);
__ push(ecx);
// Do tail-call to runtime routine.
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
// Check whether the elements is a pixel array.
// eax: value
@ -667,7 +667,7 @@ void CallIC::Generate(MacroAssembler* masm,
__ push(ebx);
// Call the entry.
CEntryStub stub;
CEntryStub stub(1);
__ mov(eax, Immediate(2));
__ mov(ebx, Immediate(f));
__ CallStub(&stub);
@ -799,7 +799,7 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
__ push(ebx); // return address
// Perform tail call to the entry.
__ TailCallRuntime(f, 2);
__ TailCallRuntime(f, 2, 1);
}
@ -927,7 +927,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
__ push(ebx); // return address
// Perform tail call to the entry.
__ TailCallRuntime(f, 2);
__ TailCallRuntime(f, 2, 1);
}
@ -967,7 +967,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
// Perform tail call to the entry.
__ TailCallRuntime(
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
}
@ -987,7 +987,7 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
__ push(ebx);
// Perform tail call to the entry.
__ TailCallRuntime(f, 3);
__ TailCallRuntime(f, 3, 1);
}
@ -1010,7 +1010,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
__ push(ecx);
// Do tail-call to runtime routine.
__ TailCallRuntime(f, 3);
__ TailCallRuntime(f, 3, 1);
}
@ -1032,7 +1032,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
// Do tail-call to runtime routine.
__ TailCallRuntime(
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
}
#undef __

View File

@ -896,7 +896,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
int num_arguments) {
int num_arguments,
int result_size) {
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
// should remove this need and make the runtime routine entry code
@ -909,7 +910,7 @@ void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
// Set the entry point and jump to the C entry runtime stub.
mov(ebx, Immediate(ext));
CEntryStub ces;
CEntryStub ces(1);
jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
}

View File

@ -256,7 +256,9 @@ class MacroAssembler: public Assembler {
// Tail call of a runtime routine (jump).
// Like JumpToBuiltin, but also takes care of passing the number
// of arguments.
void TailCallRuntime(const ExternalReference& ext, int num_arguments);
void TailCallRuntime(const ExternalReference& ext,
int num_arguments,
int result_size);
// Jump to the builtin routine.
void JumpToBuiltin(const ExternalReference& ext);

View File

@ -302,7 +302,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
__ mov(eax, Immediate(5));
__ mov(ebx, Immediate(ref));
CEntryStub stub;
CEntryStub stub(1);
__ CallStub(&stub);
}
@ -467,7 +467,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
__ TailCallRuntime(ref, 5);
__ TailCallRuntime(ref, 5, 1);
__ bind(&cleanup);
__ pop(scratch1);
@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
ExternalReference ref = ExternalReference(
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
__ TailCallRuntime(ref, 5);
__ TailCallRuntime(ref, 5, 1);
}
private:
@ -593,7 +593,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
__ mov(eax, Immediate(5));
__ mov(ebx, Immediate(ref));
CEntryStub stub;
CEntryStub stub(1);
__ CallStub(&stub);
__ LeaveInternalFrame();
@ -789,7 +789,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
// Do tail-call to the runtime system.
ExternalReference load_callback_property =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
__ TailCallRuntime(load_callback_property, 5);
__ TailCallRuntime(load_callback_property, 5, 1);
}
@ -1237,7 +1237,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
// Do tail-call to the runtime system.
ExternalReference store_callback_property =
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
__ TailCallRuntime(store_callback_property, 4);
__ TailCallRuntime(store_callback_property, 4, 1);
// Handle store cache miss.
__ bind(&miss);
@ -1290,7 +1290,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
// Do tail-call to the runtime system.
ExternalReference store_ic_property =
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
__ TailCallRuntime(store_ic_property, 3);
__ TailCallRuntime(store_ic_property, 3, 1);
// Handle store cache miss.
__ bind(&miss);

View File

@ -4556,22 +4556,25 @@ static Object* Runtime_LookupContext(Arguments args) {
}
// A mechanism to return pairs of Object*'s. This is somewhat
// compiler-dependent as it assumes that a 64-bit value (a long long)
// is returned via two registers (edx:eax on ia32). Both the ia32 and
// arm platform support this; it is mostly an issue of "coaxing" the
// compiler to do the right thing.
//
// TODO(1236026): This is a non-portable hack that should be removed.
// A mechanism to return a pair of Object pointers in registers (if possible).
// How this is achieved is calling convention-dependent.
// All currently supported x86 compiles uses calling conventions that are cdecl
// variants where a 64-bit value is returned in two 32-bit registers
// (edx:eax on ia32, r1:r0 on ARM).
// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
// In Win64 calling convention, a struct of two pointers is returned in space passed
// as a hidden first parameter.
#ifdef V8_HOST_ARCH_64_BIT
// Tested with GCC, not with MSVC.
struct ObjectPair {
Object* x;
Object* y;
};
static inline ObjectPair MakePair(Object* x, Object* y) {
ObjectPair result = {x, y};
return result; // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
// Pointers x and y returned in rax and rdx, in AMD-x64-abi.
// In Win64 they are assigned to a hidden first argument.
return result;
}
#else
typedef uint64_t ObjectPair;
@ -4582,8 +4585,6 @@ static inline ObjectPair MakePair(Object* x, Object* y) {
#endif
static inline Object* Unhole(Object* x, PropertyAttributes attributes) {
ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
USE(attributes);
@ -7619,7 +7620,7 @@ static Object* Runtime_ListNatives(Arguments args) {
HandleScope scope;
Handle<JSArray> result = Factory::NewJSArray(0);
int index = 0;
#define ADD_ENTRY(Name, argc) \
#define ADD_ENTRY(Name, argc, ressize) \
{ \
HandleScope inner; \
Handle<String> name = \
@ -7655,13 +7656,13 @@ static Object* Runtime_IS_VAR(Arguments args) {
// ----------------------------------------------------------------------------
// Implementation of Runtime
#define F(name, nargs) \
#define F(name, nargs, ressize) \
{ #name, "RuntimeStub_" #name, FUNCTION_ADDR(Runtime_##name), nargs, \
static_cast<int>(Runtime::k##name) },
static_cast<int>(Runtime::k##name), ressize },
static Runtime::Function Runtime_functions[] = {
RUNTIME_FUNCTION_LIST(F)
{ NULL, NULL, NULL, 0, -1 }
{ NULL, NULL, NULL, 0, -1, 0 }
};
#undef F

View File

@ -43,269 +43,269 @@ namespace internal {
// this problem. Please avoid large recursive macros whenever possible.
#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
/* Property access */ \
F(GetProperty, 2) \
F(KeyedGetProperty, 2) \
F(DeleteProperty, 2) \
F(HasLocalProperty, 2) \
F(HasProperty, 2) \
F(HasElement, 2) \
F(IsPropertyEnumerable, 2) \
F(GetPropertyNames, 1) \
F(GetPropertyNamesFast, 1) \
F(GetArgumentsProperty, 1) \
F(ToFastProperties, 1) \
F(ToSlowProperties, 1) \
F(GetProperty, 2, 1) \
F(KeyedGetProperty, 2, 1) \
F(DeleteProperty, 2, 1) \
F(HasLocalProperty, 2, 1) \
F(HasProperty, 2, 1) \
F(HasElement, 2, 1) \
F(IsPropertyEnumerable, 2, 1) \
F(GetPropertyNames, 1, 1) \
F(GetPropertyNamesFast, 1, 1) \
F(GetArgumentsProperty, 1, 1) \
F(ToFastProperties, 1, 1) \
F(ToSlowProperties, 1, 1) \
\
F(IsInPrototypeChain, 2) \
F(SetHiddenPrototype, 2) \
F(IsInPrototypeChain, 2, 1) \
F(SetHiddenPrototype, 2, 1) \
\
F(IsConstructCall, 0) \
F(IsConstructCall, 0, 1) \
\
/* Utilities */ \
F(GetCalledFunction, 0) \
F(GetFunctionDelegate, 1) \
F(GetConstructorDelegate, 1) \
F(NewArguments, 1) \
F(NewArgumentsFast, 3) \
F(LazyCompile, 1) \
F(SetNewFunctionAttributes, 1) \
F(GetCalledFunction, 0, 1) \
F(GetFunctionDelegate, 1, 1) \
F(GetConstructorDelegate, 1, 1) \
F(NewArguments, 1, 1) \
F(NewArgumentsFast, 3, 1) \
F(LazyCompile, 1, 1) \
F(SetNewFunctionAttributes, 1, 1) \
\
/* Array join support */ \
F(PushIfAbsent, 2) \
F(ArrayConcat, 1) \
F(PushIfAbsent, 2, 1) \
F(ArrayConcat, 1, 1) \
\
/* Conversions */ \
F(ToBool, 1) \
F(Typeof, 1) \
F(ToBool, 1, 1) \
F(Typeof, 1, 1) \
\
F(StringToNumber, 1) \
F(StringFromCharCodeArray, 1) \
F(StringParseInt, 2) \
F(StringParseFloat, 1) \
F(StringToLowerCase, 1) \
F(StringToUpperCase, 1) \
F(CharFromCode, 1) \
F(URIEscape, 1) \
F(URIUnescape, 1) \
F(StringToNumber, 1, 1) \
F(StringFromCharCodeArray, 1, 1) \
F(StringParseInt, 2, 1) \
F(StringParseFloat, 1, 1) \
F(StringToLowerCase, 1, 1) \
F(StringToUpperCase, 1, 1) \
F(CharFromCode, 1, 1) \
F(URIEscape, 1, 1) \
F(URIUnescape, 1, 1) \
\
F(NumberToString, 1) \
F(NumberToInteger, 1) \
F(NumberToJSUint32, 1) \
F(NumberToJSInt32, 1) \
F(NumberToSmi, 1) \
F(NumberToString, 1, 1) \
F(NumberToInteger, 1, 1) \
F(NumberToJSUint32, 1, 1) \
F(NumberToJSInt32, 1, 1) \
F(NumberToSmi, 1, 1) \
\
/* Arithmetic operations */ \
F(NumberAdd, 2) \
F(NumberSub, 2) \
F(NumberMul, 2) \
F(NumberDiv, 2) \
F(NumberMod, 2) \
F(NumberUnaryMinus, 1) \
F(NumberAdd, 2, 1) \
F(NumberSub, 2, 1) \
F(NumberMul, 2, 1) \
F(NumberDiv, 2, 1) \
F(NumberMod, 2, 1) \
F(NumberUnaryMinus, 1, 1) \
\
F(StringAdd, 2) \
F(StringBuilderConcat, 2) \
F(StringAdd, 2, 1) \
F(StringBuilderConcat, 2, 1) \
\
/* Bit operations */ \
F(NumberOr, 2) \
F(NumberAnd, 2) \
F(NumberXor, 2) \
F(NumberNot, 1) \
F(NumberOr, 2, 1) \
F(NumberAnd, 2, 1) \
F(NumberXor, 2, 1) \
F(NumberNot, 1, 1) \
\
F(NumberShl, 2) \
F(NumberShr, 2) \
F(NumberSar, 2) \
F(NumberShl, 2, 1) \
F(NumberShr, 2, 1) \
F(NumberSar, 2, 1) \
\
/* Comparisons */ \
F(NumberEquals, 2) \
F(StringEquals, 2) \
F(NumberEquals, 2, 1) \
F(StringEquals, 2, 1) \
\
F(NumberCompare, 3) \
F(SmiLexicographicCompare, 2) \
F(StringCompare, 2) \
F(NumberCompare, 3, 1) \
F(SmiLexicographicCompare, 2, 1) \
F(StringCompare, 2, 1) \
\
/* Math */ \
F(Math_abs, 1) \
F(Math_acos, 1) \
F(Math_asin, 1) \
F(Math_atan, 1) \
F(Math_atan2, 2) \
F(Math_ceil, 1) \
F(Math_cos, 1) \
F(Math_exp, 1) \
F(Math_floor, 1) \
F(Math_log, 1) \
F(Math_pow, 2) \
F(Math_round, 1) \
F(Math_sin, 1) \
F(Math_sqrt, 1) \
F(Math_tan, 1) \
F(Math_abs, 1, 1) \
F(Math_acos, 1, 1) \
F(Math_asin, 1, 1) \
F(Math_atan, 1, 1) \
F(Math_atan2, 2, 1) \
F(Math_ceil, 1, 1) \
F(Math_cos, 1, 1) \
F(Math_exp, 1, 1) \
F(Math_floor, 1, 1) \
F(Math_log, 1, 1) \
F(Math_pow, 2, 1) \
F(Math_round, 1, 1) \
F(Math_sin, 1, 1) \
F(Math_sqrt, 1, 1) \
F(Math_tan, 1, 1) \
\
/* Regular expressions */ \
F(RegExpCompile, 3) \
F(RegExpExec, 4) \
F(RegExpCompile, 3, 1) \
F(RegExpExec, 4, 1) \
\
/* Strings */ \
F(StringCharCodeAt, 2) \
F(StringIndexOf, 3) \
F(StringLastIndexOf, 3) \
F(StringLocaleCompare, 2) \
F(StringSlice, 3) \
F(StringReplaceRegExpWithString, 4) \
F(StringMatch, 3) \
F(StringCharCodeAt, 2, 1) \
F(StringIndexOf, 3, 1) \
F(StringLastIndexOf, 3, 1) \
F(StringLocaleCompare, 2, 1) \
F(StringSlice, 3, 1) \
F(StringReplaceRegExpWithString, 4, 1) \
F(StringMatch, 3, 1) \
\
/* Numbers */ \
F(NumberToRadixString, 2) \
F(NumberToFixed, 2) \
F(NumberToExponential, 2) \
F(NumberToPrecision, 2)
F(NumberToRadixString, 2, 1) \
F(NumberToFixed, 2, 1) \
F(NumberToExponential, 2, 1) \
F(NumberToPrecision, 2, 1)
#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
/* Reflection */ \
F(FunctionSetInstanceClassName, 2) \
F(FunctionSetLength, 2) \
F(FunctionSetPrototype, 2) \
F(FunctionGetName, 1) \
F(FunctionSetName, 2) \
F(FunctionGetSourceCode, 1) \
F(FunctionGetScript, 1) \
F(FunctionGetScriptSourcePosition, 1) \
F(FunctionGetPositionForOffset, 2) \
F(FunctionIsAPIFunction, 1) \
F(GetScript, 1) \
F(CollectStackTrace, 2) \
F(FunctionSetInstanceClassName, 2, 1) \
F(FunctionSetLength, 2, 1) \
F(FunctionSetPrototype, 2, 1) \
F(FunctionGetName, 1, 1) \
F(FunctionSetName, 2, 1) \
F(FunctionGetSourceCode, 1, 1) \
F(FunctionGetScript, 1, 1) \
F(FunctionGetScriptSourcePosition, 1, 1) \
F(FunctionGetPositionForOffset, 2, 1) \
F(FunctionIsAPIFunction, 1, 1) \
F(GetScript, 1, 1) \
F(CollectStackTrace, 2, 1) \
\
F(ClassOf, 1) \
F(SetCode, 2) \
F(ClassOf, 1, 1) \
F(SetCode, 2, 1) \
\
F(CreateApiFunction, 1) \
F(IsTemplate, 1) \
F(GetTemplateField, 2) \
F(DisableAccessChecks, 1) \
F(EnableAccessChecks, 1) \
F(CreateApiFunction, 1, 1) \
F(IsTemplate, 1, 1) \
F(GetTemplateField, 2, 1) \
F(DisableAccessChecks, 1, 1) \
F(EnableAccessChecks, 1, 1) \
\
/* Dates */ \
F(DateCurrentTime, 0) \
F(DateParseString, 2) \
F(DateLocalTimezone, 1) \
F(DateLocalTimeOffset, 0) \
F(DateDaylightSavingsOffset, 1) \
F(DateCurrentTime, 0, 1) \
F(DateParseString, 2, 1) \
F(DateLocalTimezone, 1, 1) \
F(DateLocalTimeOffset, 0, 1) \
F(DateDaylightSavingsOffset, 1, 1) \
\
/* Numbers */ \
F(NumberIsFinite, 1) \
F(NumberIsFinite, 1, 1) \
\
/* Globals */ \
F(CompileString, 2) \
F(GlobalPrint, 1) \
F(CompileString, 2, 1) \
F(GlobalPrint, 1, 1) \
\
/* Eval */ \
F(GlobalReceiver, 1) \
F(ResolvePossiblyDirectEval, 2) \
F(GlobalReceiver, 1, 1) \
F(ResolvePossiblyDirectEval, 2, 1) \
\
F(SetProperty, -1 /* 3 or 4 */) \
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */) \
F(SetProperty, -1 /* 3 or 4 */, 1) \
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \
\
/* Arrays */ \
F(RemoveArrayHoles, 2) \
F(GetArrayKeys, 2) \
F(MoveArrayContents, 2) \
F(EstimateNumberOfElements, 1) \
F(RemoveArrayHoles, 2, 1) \
F(GetArrayKeys, 2, 1) \
F(MoveArrayContents, 2, 1) \
F(EstimateNumberOfElements, 1, 1) \
\
/* Getters and Setters */ \
F(DefineAccessor, -1 /* 4 or 5 */) \
F(LookupAccessor, 3) \
F(DefineAccessor, -1 /* 4 or 5 */, 1) \
F(LookupAccessor, 3, 1) \
\
/* Literals */ \
F(MaterializeRegExpLiteral, 4)\
F(CreateArrayLiteralBoilerplate, 3) \
F(CreateObjectLiteralBoilerplate, 3) \
F(CloneLiteralBoilerplate, 1) \
F(CloneShallowLiteralBoilerplate, 1) \
F(MaterializeRegExpLiteral, 4, 1)\
F(CreateArrayLiteralBoilerplate, 3, 1) \
F(CreateObjectLiteralBoilerplate, 3, 1) \
F(CloneLiteralBoilerplate, 1, 1) \
F(CloneShallowLiteralBoilerplate, 1, 1) \
\
/* Catch context extension objects */ \
F(CreateCatchExtensionObject, 2) \
F(CreateCatchExtensionObject, 2, 1) \
\
/* Statements */ \
F(NewClosure, 2) \
F(NewObject, 1) \
F(Throw, 1) \
F(ReThrow, 1) \
F(ThrowReferenceError, 1) \
F(StackGuard, 1) \
F(NewClosure, 2, 1) \
F(NewObject, 1, 1) \
F(Throw, 1, 1) \
F(ReThrow, 1, 1) \
F(ThrowReferenceError, 1, 1) \
F(StackGuard, 1, 1) \
\
/* Contexts */ \
F(NewContext, 1) \
F(PushContext, 1) \
F(PushCatchContext, 1) \
F(LookupContext, 2) \
F(LoadContextSlot, 2) \
F(LoadContextSlotNoReferenceError, 2) \
F(StoreContextSlot, 3) \
F(NewContext, 1, 1) \
F(PushContext, 1, 1) \
F(PushCatchContext, 1, 1) \
F(LookupContext, 2, 1) \
F(LoadContextSlot, 2, 2) \
F(LoadContextSlotNoReferenceError, 2, 2) \
F(StoreContextSlot, 3, 1) \
\
/* Declarations and initialization */ \
F(DeclareGlobals, 3) \
F(DeclareContextSlot, 4) \
F(InitializeVarGlobal, -1 /* 1 or 2 */) \
F(InitializeConstGlobal, 2) \
F(InitializeConstContextSlot, 3) \
F(OptimizeObjectForAddingMultipleProperties, 2) \
F(TransformToFastProperties, 1) \
F(DeclareGlobals, 3, 1) \
F(DeclareContextSlot, 4, 1) \
F(InitializeVarGlobal, -1 /* 1 or 2 */, 1) \
F(InitializeConstGlobal, 2, 1) \
F(InitializeConstContextSlot, 3, 1) \
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
F(TransformToFastProperties, 1, 1) \
\
/* Debugging */ \
F(DebugPrint, 1) \
F(DebugTrace, 0) \
F(TraceEnter, 0) \
F(TraceExit, 1) \
F(Abort, 2) \
F(DebugPrint, 1, 1) \
F(DebugTrace, 0, 1) \
F(TraceEnter, 0, 1) \
F(TraceExit, 1, 1) \
F(Abort, 2, 1) \
/* Logging */ \
F(Log, 2) \
F(Log, 2, 1) \
\
/* Pseudo functions - handled as macros by parser */ \
F(IS_VAR, 1)
F(IS_VAR, 1, 1)
#ifdef ENABLE_DEBUGGER_SUPPORT
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
/* Debugger support*/ \
F(DebugBreak, 0) \
F(SetDebugEventListener, 2) \
F(Break, 0) \
F(DebugGetPropertyDetails, 2) \
F(DebugGetProperty, 2) \
F(DebugLocalPropertyNames, 1) \
F(DebugLocalElementNames, 1) \
F(DebugPropertyTypeFromDetails, 1) \
F(DebugPropertyAttributesFromDetails, 1) \
F(DebugPropertyIndexFromDetails, 1) \
F(DebugInterceptorInfo, 1) \
F(DebugNamedInterceptorPropertyNames, 1) \
F(DebugIndexedInterceptorElementNames, 1) \
F(DebugNamedInterceptorPropertyValue, 2) \
F(DebugIndexedInterceptorElementValue, 2) \
F(CheckExecutionState, 1) \
F(GetFrameCount, 1) \
F(GetFrameDetails, 2) \
F(GetScopeCount, 2) \
F(GetScopeDetails, 3) \
F(DebugPrintScopes, 0) \
F(GetCFrames, 1) \
F(GetThreadCount, 1) \
F(GetThreadDetails, 2) \
F(GetBreakLocations, 1) \
F(SetFunctionBreakPoint, 3) \
F(SetScriptBreakPoint, 3) \
F(ClearBreakPoint, 1) \
F(ChangeBreakOnException, 2) \
F(PrepareStep, 3) \
F(ClearStepping, 0) \
F(DebugEvaluate, 4) \
F(DebugEvaluateGlobal, 3) \
F(DebugGetLoadedScripts, 0) \
F(DebugReferencedBy, 3) \
F(DebugConstructedBy, 2) \
F(DebugGetPrototype, 1) \
F(SystemBreak, 0) \
F(DebugDisassembleFunction, 1) \
F(DebugDisassembleConstructor, 1) \
F(FunctionGetInferredName, 1)
F(DebugBreak, 0, 1) \
F(SetDebugEventListener, 2, 1) \
F(Break, 0, 1) \
F(DebugGetPropertyDetails, 2, 1) \
F(DebugGetProperty, 2, 1) \
F(DebugLocalPropertyNames, 1, 1) \
F(DebugLocalElementNames, 1, 1) \
F(DebugPropertyTypeFromDetails, 1, 1) \
F(DebugPropertyAttributesFromDetails, 1, 1) \
F(DebugPropertyIndexFromDetails, 1, 1) \
F(DebugInterceptorInfo, 1, 1) \
F(DebugNamedInterceptorPropertyNames, 1, 1) \
F(DebugIndexedInterceptorElementNames, 1, 1) \
F(DebugNamedInterceptorPropertyValue, 2, 1) \
F(DebugIndexedInterceptorElementValue, 2, 1) \
F(CheckExecutionState, 1, 1) \
F(GetFrameCount, 1, 1) \
F(GetFrameDetails, 2, 1) \
F(GetScopeCount, 2, 1) \
F(GetScopeDetails, 3, 1) \
F(DebugPrintScopes, 0, 1) \
F(GetCFrames, 1, 1) \
F(GetThreadCount, 1, 1) \
F(GetThreadDetails, 2, 1) \
F(GetBreakLocations, 1, 1) \
F(SetFunctionBreakPoint, 3, 1) \
F(SetScriptBreakPoint, 3, 1) \
F(ClearBreakPoint, 1, 1) \
F(ChangeBreakOnException, 2, 1) \
F(PrepareStep, 3, 1) \
F(ClearStepping, 0, 1) \
F(DebugEvaluate, 4, 1) \
F(DebugEvaluateGlobal, 3, 1) \
F(DebugGetLoadedScripts, 0, 1) \
F(DebugReferencedBy, 3, 1) \
F(DebugConstructedBy, 2, 1) \
F(DebugGetPrototype, 1, 1) \
F(SystemBreak, 0, 1) \
F(DebugDisassembleFunction, 1, 1) \
F(DebugDisassembleConstructor, 1, 1) \
F(FunctionGetInferredName, 1, 1)
#else
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
#endif
@ -313,7 +313,7 @@ namespace internal {
#ifdef DEBUG
#define RUNTIME_FUNCTION_LIST_DEBUG(F) \
/* Testing */ \
F(ListNatives, 0)
F(ListNatives, 0, 1)
#else
#define RUNTIME_FUNCTION_LIST_DEBUG(F)
#endif
@ -336,7 +336,7 @@ namespace internal {
class Runtime : public AllStatic {
public:
enum FunctionId {
#define F(name, nargs) k##name,
#define F(name, nargs, ressize) k##name,
RUNTIME_FUNCTION_LIST(F)
kNofFunctions
#undef F
@ -357,6 +357,9 @@ class Runtime : public AllStatic {
// arguments.
int nargs;
int stub_id;
// Size of result, if complex (larger than a single pointer),
// otherwise zero.
int result_size;
};
// Get the runtime function with the given function id.

View File

@ -541,7 +541,7 @@ void ExternalReferenceTable::PopulateTable() {
#undef DEF_ENTRY_A
// Runtime functions
#define RUNTIME_ENTRY(name, nargs) \
#define RUNTIME_ENTRY(name, nargs, ressize) \
{ RUNTIME_FUNCTION, \
Runtime::k##name, \
"Runtime::" #name },

View File

@ -44,7 +44,7 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
// rax, but JumpToBuiltin expects rax to contain the number of
// arguments including the receiver.
__ incq(rax);
__ JumpToBuiltin(ExternalReference(id));
__ JumpToBuiltin(ExternalReference(id), 1);
}

View File

@ -6829,7 +6829,8 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
// Do the runtime call to allocate the arguments object.
__ bind(&runtime);
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
Runtime::Function* f = Runtime::FunctionForId(Runtime::kNewArgumentsFast);
__ TailCallRuntime(ExternalReference(f), 3, f->result_size);
}
@ -6891,7 +6892,9 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
__ pop(rbx); // Return address.
__ push(rdx);
__ push(rbx);
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
Runtime::Function* f =
Runtime::FunctionForId(Runtime::kGetArgumentsProperty);
__ TailCallRuntime(ExternalReference(f), 1, f->result_size);
}
@ -6915,6 +6918,23 @@ void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
}
int CEntryStub::MinorKey() {
ASSERT(result_size_ <= 2);
#ifdef _WIN64
// Simple results returned in rax (using default code).
// Complex results must be written to address passed as first argument.
// Use even numbers for minor keys, reserving the odd numbers for
// CEntryDebugBreakStub.
return (result_size_ < 2) ? 0 : result_size_ * 2;
#else
// Single results returned in rax (both AMD64 and Win64 calling conventions)
// and a struct of two pointers in rax+rdx (AMD64 calling convention only)
// by default.
return 0;
#endif
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
// Check that stack should contain next handler, frame pointer, state and
// return address in that order.
@ -6986,8 +7006,18 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
__ movq(Operand(rsp, 4 * kPointerSize), r14); // argc.
__ movq(Operand(rsp, 5 * kPointerSize), r15); // argv.
// Pass a pointer to the Arguments object as the first argument.
__ lea(rcx, Operand(rsp, 4 * kPointerSize));
if (result_size_ < 2) {
// Pass a pointer to the Arguments object as the first argument.
// Return result in single register (rax).
__ lea(rcx, Operand(rsp, 4 * kPointerSize));
} else {
ASSERT_EQ(2, result_size_);
// Pass a pointer to the result location as the first argument.
__ lea(rcx, Operand(rsp, 6 * kPointerSize));
// Pass a pointer to the Arguments object as the second argument.
__ lea(rdx, Operand(rsp, 4 * kPointerSize));
}
#else // ! defined(_WIN64)
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
__ movq(rdi, r14); // argc.
@ -7010,7 +7040,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ j(zero, &failure_returned);
// Exit the JavaScript to C++ exit frame.
__ LeaveExitFrame(frame_type);
__ LeaveExitFrame(frame_type, result_size_);
__ ret(0);
// Handling of failure.
@ -7146,7 +7176,7 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
StackFrame::EXIT;
// Enter the exit frame that transitions from JavaScript to C++.
__ EnterExitFrame(frame_type);
__ EnterExitFrame(frame_type, result_size_);
// rax: Holds the context at this point, but should not be used.
// On entry to code generated by GenerateCore, it must hold
@ -7333,7 +7363,8 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
__ push(rax);
// Do tail-call to runtime routine.
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
Runtime::Function* f = Runtime::FunctionForId(Runtime::kStackGuard);
__ TailCallRuntime(ExternalReference(f), 1, f->result_size);
}

View File

@ -236,7 +236,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm,
__ push(rbx); // return address
// Perform tail call to the entry.
__ TailCallRuntime(f, 2);
__ TailCallRuntime(f, 2, 1);
}
@ -373,7 +373,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
__ push(rcx); // return address
// Do tail-call to runtime routine.
__ TailCallRuntime(f, 3);
__ TailCallRuntime(f, 3, 1);
}
@ -394,7 +394,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
// Do tail-call to runtime routine.
__ TailCallRuntime(
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
}
@ -460,7 +460,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
__ push(rax);
__ push(rcx);
// Do tail-call to runtime routine.
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
// Extra capacity case: Check if there is extra capacity to
@ -532,7 +532,7 @@ void CallIC::Generate(MacroAssembler* masm,
__ push(rbx);
// Call the entry.
CEntryStub stub;
CEntryStub stub(1);
__ movq(rax, Immediate(2));
__ movq(rbx, f);
__ CallStub(&stub);
@ -763,7 +763,7 @@ void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
__ push(rbx); // return address
// Perform tail call to the entry.
__ TailCallRuntime(f, 2);
__ TailCallRuntime(f, 2, 1);
}
@ -940,7 +940,7 @@ void StoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
__ push(rbx); // return address
// Perform tail call to the entry.
__ TailCallRuntime(f, 3);
__ TailCallRuntime(f, 3, 1);
}
void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
@ -959,7 +959,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
// Perform tail call to the entry.
__ TailCallRuntime(
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
}
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {

View File

@ -318,7 +318,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
int num_arguments) {
int num_arguments,
int result_size) {
// ----------- S t a t e -------------
// -- rsp[0] : return address
// -- rsp[8] : argument num_arguments - 1
@ -331,14 +332,15 @@ void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
// should remove this need and make the runtime routine entry code
// smarter.
movq(rax, Immediate(num_arguments));
JumpToBuiltin(ext);
JumpToBuiltin(ext, result_size);
}
void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
void MacroAssembler::JumpToBuiltin(const ExternalReference& ext,
int result_size) {
// Set the entry point and jump to the C entry runtime stub.
movq(rbx, ext);
CEntryStub ces;
CEntryStub ces(result_size);
movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET);
jmp(kScratchRegister);
}
@ -971,7 +973,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
void MacroAssembler::EnterExitFrame(StackFrame::Type type, int result_size) {
ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
// Setup the frame structure on the stack.
@ -1016,6 +1018,21 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
}
#endif
#ifdef _WIN64
// Reserve space on stack for result and argument structures, if necessary.
int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize;
// Reserve space for the Arguments object. The Windows 64-bit ABI
// requires us to pass this structure as a pointer to its location on
// the stack. The structure contains 2 values.
int argument_stack_space = 2 * kPointerSize;
// We also need backing space for 4 parameters, even though
// we only pass one or two parameter, and it is in a register.
int argument_mirror_space = 4 * kPointerSize;
int total_stack_space =
argument_mirror_space + argument_stack_space + result_stack_space;
subq(rsp, Immediate(total_stack_space));
#endif
// Get the required frame alignment for the OS.
static const int kFrameAlignment = OS::ActivationFrameAlignment();
if (kFrameAlignment > 0) {
@ -1024,30 +1041,19 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
and_(rsp, kScratchRegister);
}
#ifdef _WIN64
// Reserve space for the Arguments object. The Windows 64-bit ABI
// requires us to pass this structure as a pointer to its location on
// the stack. The structure contains 2 pointers.
// The structure on the stack must be 16-byte aligned.
// We also need backing space for 4 parameters, even though
// we only pass one parameter, and it is in a register.
subq(rsp, Immediate(6 * kPointerSize));
ASSERT(kFrameAlignment == 2 * kPointerSize); // Change the padding if needed.
#endif
// Patch the saved entry sp.
movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
}
void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) {
// Registers:
// r15 : argv
#ifdef ENABLE_DEBUGGER_SUPPORT
// Restore the memory copy of the registers by digging them out from
// the stack. This is needed to allow nested break points.
if (type == StackFrame::EXIT_DEBUG) {
// It's okay to clobber register ebx below because we don't need
// It's okay to clobber register rbx below because we don't need
// the function pointer after this.
const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;
int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;
@ -1060,7 +1066,18 @@ void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
movq(rcx, Operand(rbp, 1 * kPointerSize));
movq(rbp, Operand(rbp, 0 * kPointerSize));
// Pop the arguments and the receiver from the caller stack.
#ifdef _WIN64
// If return value is on the stack, pop it to registers.
if (result_size > 1) {
ASSERT_EQ(2, result_size);
// Position above 4 argument mirrors and arguments object.
movq(rax, Operand(rsp, 6 * kPointerSize));
movq(rdx, Operand(rsp, 7 * kPointerSize));
}
#endif
// Pop everything up to and including the arguments and the receiver
// from the caller stack.
lea(rsp, Operand(r15, 1 * kPointerSize));
// Restore current context from top and clear it in debug mode.

View File

@ -87,15 +87,15 @@ class MacroAssembler: public Assembler {
void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
// Enter specific kind of exit frame; either EXIT or
// EXIT_DEBUG. Expects the number of arguments in register eax and
// sets up the number of arguments in register edi and the pointer
// to the first argument in register esi.
void EnterExitFrame(StackFrame::Type type);
// EXIT_DEBUG. Expects the number of arguments in register rax and
// sets up the number of arguments in register rdi and the pointer
// to the first argument in register rsi.
void EnterExitFrame(StackFrame::Type type, int result_size = 1);
// Leave the current exit frame. Expects the return value in
// register eax:edx (untouched) and the pointer to the first
// argument in register esi.
void LeaveExitFrame(StackFrame::Type type);
// Leave the current exit frame. Expects/provides the return value in
// register rax:rdx (untouched) and the pointer to the first
// argument in register rsi.
void LeaveExitFrame(StackFrame::Type type, int result_size = 1);
// ---------------------------------------------------------------------------
@ -298,10 +298,12 @@ class MacroAssembler: public Assembler {
// Tail call of a runtime routine (jump).
// Like JumpToBuiltin, but also takes care of passing the number
// of arguments.
void TailCallRuntime(const ExternalReference& ext, int num_arguments);
void TailCallRuntime(const ExternalReference& ext,
int num_arguments,
int result_size);
// Jump to the builtin routine.
void JumpToBuiltin(const ExternalReference& ext);
void JumpToBuiltin(const ExternalReference& ext, int result_size);
// ---------------------------------------------------------------------------

View File

@ -612,7 +612,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
// MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
// Store register parameters in pre-allocated stack slots,
__ movq(Operand(rbp, kInputString), rcx);
__ movzxlq(Operand(rbp, kStartIndex), rdx); // Passed as int in eax.
__ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx.
__ movq(Operand(rbp, kInputStart), r8);
__ movq(Operand(rbp, kInputEnd), r9);
// Callee-save on Win64.

View File

@ -354,7 +354,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
__ movq(rax, Immediate(5));
__ movq(rbx, ref);
CEntryStub stub;
CEntryStub stub(1);
__ CallStub(&stub);
}
@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
__ TailCallRuntime(ref, 5);
__ TailCallRuntime(ref, 5, 1);
__ bind(&cleanup);
__ pop(scratch1);
@ -511,7 +511,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
ExternalReference ref = ExternalReference(
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
__ TailCallRuntime(ref, 5);
__ TailCallRuntime(ref, 5, 1);
}
private:
@ -661,7 +661,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
__ movq(rax, Immediate(5));
__ movq(rbx, ref);
CEntryStub stub;
CEntryStub stub(1);
__ CallStub(&stub);
__ LeaveInternalFrame();
@ -1362,7 +1362,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
// Do tail-call to the runtime system.
ExternalReference store_callback_property =
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
__ TailCallRuntime(store_callback_property, 4);
__ TailCallRuntime(store_callback_property, 4, 1);
// Handle store cache miss.
__ bind(&miss);
@ -1450,7 +1450,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
// Do tail-call to the runtime system.
ExternalReference store_ic_property =
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
__ TailCallRuntime(store_ic_property, 3);
__ TailCallRuntime(store_ic_property, 3, 1);
// Handle store cache miss.
__ bind(&miss);
@ -1652,7 +1652,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
// Do tail-call to the runtime system.
ExternalReference load_callback_property =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
__ TailCallRuntime(load_callback_property, 5);
__ TailCallRuntime(load_callback_property, 5, 1);
}