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:
parent
ae062d5df1
commit
8f60f1a46f
@ -5623,7 +5623,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
|||||||
// argument, so give it a Smi.
|
// argument, so give it a Smi.
|
||||||
__ mov(r0, Operand(Smi::FromInt(0)));
|
__ mov(r0, Operand(Smi::FromInt(0)));
|
||||||
__ push(r0);
|
__ push(r0);
|
||||||
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
|
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
|
||||||
|
|
||||||
__ StubReturn(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) {
|
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
||||||
// r0 holds the exception.
|
// r0 holds the exception.
|
||||||
|
|
||||||
@ -6195,7 +6202,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
|
|||||||
// by calling the runtime system.
|
// by calling the runtime system.
|
||||||
__ bind(&slow);
|
__ bind(&slow);
|
||||||
__ push(r1);
|
__ 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.
|
// Do the runtime call to allocate the arguments object.
|
||||||
__ bind(&runtime);
|
__ bind(&runtime);
|
||||||
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
|
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ void CallIC::Generate(MacroAssembler* masm,
|
|||||||
__ mov(r0, Operand(2));
|
__ mov(r0, Operand(2));
|
||||||
__ mov(r1, Operand(f));
|
__ mov(r1, Operand(f));
|
||||||
|
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
__ CallStub(&stub);
|
__ CallStub(&stub);
|
||||||
|
|
||||||
// Move result to r1 and leave the internal frame.
|
// 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());
|
__ stm(db_w, sp, r2.bit() | r3.bit());
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// 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());
|
__ ldm(ia, sp, r2.bit() | r3.bit());
|
||||||
__ stm(db_w, 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());
|
__ ldm(ia, sp, r0.bit() | r1.bit());
|
||||||
__ stm(db_w, sp, r0.bit() | r1.bit());
|
__ stm(db_w, sp, r0.bit() | r1.bit());
|
||||||
// Do tail-call to runtime routine.
|
// Do tail-call to runtime routine.
|
||||||
__ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2);
|
__ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2, 1);
|
||||||
|
|
||||||
// Fast case: Do the load.
|
// Fast case: Do the load.
|
||||||
__ bind(&fast);
|
__ bind(&fast);
|
||||||
@ -626,7 +626,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm,
|
|||||||
__ ldm(ia, sp, r2.bit() | r3.bit());
|
__ ldm(ia, sp, r2.bit() | r3.bit());
|
||||||
__ stm(db_w, sp, r0.bit() | 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
|
__ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object
|
||||||
__ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
|
__ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
|
||||||
// Do tail-call to runtime routine.
|
// 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
|
// Extra capacity case: Check if there is extra capacity to
|
||||||
// perform the store and update the length. Used for adding one
|
// 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.
|
// Perform tail call to the entry.
|
||||||
__ TailCallRuntime(
|
__ 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.
|
// Perform tail call to the entry.
|
||||||
__ TailCallRuntime(
|
__ 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());
|
__ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// Perform tail call to the entry.
|
||||||
__ TailCallRuntime(f, 3);
|
__ TailCallRuntime(f, 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -999,7 +999,8 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
|
|||||||
|
|
||||||
|
|
||||||
void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
|
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
|
// TODO(1236192): Most runtime routines don't need the number of
|
||||||
// arguments passed in because it is constant. At some point we
|
// arguments passed in because it is constant. At some point we
|
||||||
// should remove this need and make the runtime routine entry code
|
// 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);
|
ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
|
||||||
#endif
|
#endif
|
||||||
mov(r1, Operand(builtin));
|
mov(r1, Operand(builtin));
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,9 @@ class MacroAssembler: public Assembler {
|
|||||||
// Tail call of a runtime routine (jump).
|
// Tail call of a runtime routine (jump).
|
||||||
// Like JumpToBuiltin, but also takes care of passing the number
|
// Like JumpToBuiltin, but also takes care of passing the number
|
||||||
// of parameters.
|
// 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.
|
// Jump to the builtin routine.
|
||||||
void JumpToBuiltin(const ExternalReference& builtin);
|
void JumpToBuiltin(const ExternalReference& builtin);
|
||||||
|
@ -478,7 +478,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
|
|||||||
// Do tail-call to the runtime system.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference load_callback_property =
|
ExternalReference load_callback_property =
|
||||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
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.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference load_ic_property =
|
ExternalReference load_ic_property =
|
||||||
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
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.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference store_callback_property =
|
ExternalReference store_callback_property =
|
||||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
||||||
__ TailCallRuntime(store_callback_property, 4);
|
__ TailCallRuntime(store_callback_property, 4, 1);
|
||||||
|
|
||||||
// Handle store cache miss.
|
// Handle store cache miss.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
@ -936,7 +936,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
|
|||||||
// Do tail-call to the runtime system.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference store_ic_property =
|
ExternalReference store_ic_property =
|
||||||
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
||||||
__ TailCallRuntime(store_ic_property, 3);
|
__ TailCallRuntime(store_ic_property, 3, 1);
|
||||||
|
|
||||||
// Handle store cache miss.
|
// Handle store cache miss.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
|
@ -517,7 +517,10 @@ const char* RuntimeStub::GetName() {
|
|||||||
|
|
||||||
|
|
||||||
void RuntimeStub::Generate(MacroAssembler* masm) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ class CompareStub: public CodeStub {
|
|||||||
|
|
||||||
class CEntryStub : public CodeStub {
|
class CEntryStub : public CodeStub {
|
||||||
public:
|
public:
|
||||||
CEntryStub() { }
|
explicit CEntryStub(int result_size) : result_size_(result_size) { }
|
||||||
|
|
||||||
void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
|
void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
|
||||||
|
|
||||||
@ -302,10 +302,14 @@ class CEntryStub : public CodeStub {
|
|||||||
void GenerateThrowTOS(MacroAssembler* masm);
|
void GenerateThrowTOS(MacroAssembler* masm);
|
||||||
void GenerateThrowUncatchable(MacroAssembler* masm,
|
void GenerateThrowUncatchable(MacroAssembler* masm,
|
||||||
UncatchableExceptionType type);
|
UncatchableExceptionType type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Number of pointers/values returned.
|
||||||
|
int result_size_;
|
||||||
|
|
||||||
Major MajorKey() { return CEntry; }
|
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"; }
|
const char* GetName() { return "CEntryStub"; }
|
||||||
};
|
};
|
||||||
@ -313,7 +317,7 @@ class CEntryStub : public CodeStub {
|
|||||||
|
|
||||||
class CEntryDebugBreakStub : public CEntryStub {
|
class CEntryDebugBreakStub : public CEntryStub {
|
||||||
public:
|
public:
|
||||||
CEntryDebugBreakStub() { }
|
CEntryDebugBreakStub() : CEntryStub(1) { }
|
||||||
|
|
||||||
void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
|
void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
|
||||||
|
|
||||||
|
@ -1319,7 +1319,7 @@ bool Heap::CreateApiObjects() {
|
|||||||
|
|
||||||
|
|
||||||
void Heap::CreateCEntryStub() {
|
void Heap::CreateCEntryStub() {
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
set_c_entry_code(*stub.GetCode());
|
set_c_entry_code(*stub.GetCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6886,7 +6886,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
|
|||||||
__ j(above_equal, &string1);
|
__ j(above_equal, &string1);
|
||||||
|
|
||||||
// First and second argument are strings.
|
// First and second argument are strings.
|
||||||
__ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2);
|
__ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
|
||||||
|
|
||||||
// Only first argument is a string.
|
// Only first argument is a string.
|
||||||
__ bind(&string1);
|
__ bind(&string1);
|
||||||
@ -7175,7 +7175,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
|
|||||||
__ pop(ebx); // Return address.
|
__ pop(ebx); // Return address.
|
||||||
__ push(edx);
|
__ push(edx);
|
||||||
__ push(ebx);
|
__ 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.
|
// Do the runtime call to allocate the arguments object.
|
||||||
__ bind(&runtime);
|
__ bind(&runtime);
|
||||||
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
|
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7436,7 +7436,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
|||||||
__ push(eax);
|
__ push(eax);
|
||||||
|
|
||||||
// Do tail-call to runtime routine.
|
// 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) {
|
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
||||||
// eax holds the exception.
|
// eax holds the exception.
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
__ push(eax);
|
__ push(eax);
|
||||||
__ push(ecx);
|
__ push(ecx);
|
||||||
// Do tail-call to runtime routine.
|
// 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.
|
// Check whether the elements is a pixel array.
|
||||||
// eax: value
|
// eax: value
|
||||||
@ -667,7 +667,7 @@ void CallIC::Generate(MacroAssembler* masm,
|
|||||||
__ push(ebx);
|
__ push(ebx);
|
||||||
|
|
||||||
// Call the entry.
|
// Call the entry.
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
__ mov(eax, Immediate(2));
|
__ mov(eax, Immediate(2));
|
||||||
__ mov(ebx, Immediate(f));
|
__ mov(ebx, Immediate(f));
|
||||||
__ CallStub(&stub);
|
__ CallStub(&stub);
|
||||||
@ -799,7 +799,7 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
|||||||
__ push(ebx); // return address
|
__ push(ebx); // return address
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// 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
|
__ push(ebx); // return address
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// 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.
|
// Perform tail call to the entry.
|
||||||
__ TailCallRuntime(
|
__ 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);
|
__ push(ebx);
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// 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);
|
__ push(ecx);
|
||||||
|
|
||||||
// Do tail-call to runtime routine.
|
// 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.
|
// Do tail-call to runtime routine.
|
||||||
__ TailCallRuntime(
|
__ TailCallRuntime(
|
||||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef __
|
#undef __
|
||||||
|
@ -896,7 +896,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
|
|||||||
|
|
||||||
|
|
||||||
void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
|
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
|
// TODO(1236192): Most runtime routines don't need the number of
|
||||||
// arguments passed in because it is constant. At some point we
|
// arguments passed in because it is constant. At some point we
|
||||||
// should remove this need and make the runtime routine entry code
|
// 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) {
|
void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
|
||||||
// Set the entry point and jump to the C entry runtime stub.
|
// Set the entry point and jump to the C entry runtime stub.
|
||||||
mov(ebx, Immediate(ext));
|
mov(ebx, Immediate(ext));
|
||||||
CEntryStub ces;
|
CEntryStub ces(1);
|
||||||
jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
|
jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,9 @@ class MacroAssembler: public Assembler {
|
|||||||
// Tail call of a runtime routine (jump).
|
// Tail call of a runtime routine (jump).
|
||||||
// Like JumpToBuiltin, but also takes care of passing the number
|
// Like JumpToBuiltin, but also takes care of passing the number
|
||||||
// of arguments.
|
// 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.
|
// Jump to the builtin routine.
|
||||||
void JumpToBuiltin(const ExternalReference& ext);
|
void JumpToBuiltin(const ExternalReference& ext);
|
||||||
|
@ -302,7 +302,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
|
|||||||
__ mov(eax, Immediate(5));
|
__ mov(eax, Immediate(5));
|
||||||
__ mov(ebx, Immediate(ref));
|
__ mov(ebx, Immediate(ref));
|
||||||
|
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
__ CallStub(&stub);
|
__ CallStub(&stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,7 +467,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
|||||||
|
|
||||||
ExternalReference ref =
|
ExternalReference ref =
|
||||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||||
__ TailCallRuntime(ref, 5);
|
__ TailCallRuntime(ref, 5, 1);
|
||||||
|
|
||||||
__ bind(&cleanup);
|
__ bind(&cleanup);
|
||||||
__ pop(scratch1);
|
__ pop(scratch1);
|
||||||
@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
|||||||
|
|
||||||
ExternalReference ref = ExternalReference(
|
ExternalReference ref = ExternalReference(
|
||||||
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
||||||
__ TailCallRuntime(ref, 5);
|
__ TailCallRuntime(ref, 5, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -593,7 +593,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|||||||
__ mov(eax, Immediate(5));
|
__ mov(eax, Immediate(5));
|
||||||
__ mov(ebx, Immediate(ref));
|
__ mov(ebx, Immediate(ref));
|
||||||
|
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
__ CallStub(&stub);
|
__ CallStub(&stub);
|
||||||
|
|
||||||
__ LeaveInternalFrame();
|
__ LeaveInternalFrame();
|
||||||
@ -789,7 +789,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
|
|||||||
// Do tail-call to the runtime system.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference load_callback_property =
|
ExternalReference load_callback_property =
|
||||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
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.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference store_callback_property =
|
ExternalReference store_callback_property =
|
||||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
||||||
__ TailCallRuntime(store_callback_property, 4);
|
__ TailCallRuntime(store_callback_property, 4, 1);
|
||||||
|
|
||||||
// Handle store cache miss.
|
// Handle store cache miss.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
@ -1290,7 +1290,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
|
|||||||
// Do tail-call to the runtime system.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference store_ic_property =
|
ExternalReference store_ic_property =
|
||||||
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
||||||
__ TailCallRuntime(store_ic_property, 3);
|
__ TailCallRuntime(store_ic_property, 3, 1);
|
||||||
|
|
||||||
// Handle store cache miss.
|
// Handle store cache miss.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
|
@ -4556,22 +4556,25 @@ static Object* Runtime_LookupContext(Arguments args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// A mechanism to return pairs of Object*'s. This is somewhat
|
// A mechanism to return a pair of Object pointers in registers (if possible).
|
||||||
// compiler-dependent as it assumes that a 64-bit value (a long long)
|
// How this is achieved is calling convention-dependent.
|
||||||
// is returned via two registers (edx:eax on ia32). Both the ia32 and
|
// All currently supported x86 compiles uses calling conventions that are cdecl
|
||||||
// arm platform support this; it is mostly an issue of "coaxing" the
|
// variants where a 64-bit value is returned in two 32-bit registers
|
||||||
// compiler to do the right thing.
|
// (edx:eax on ia32, r1:r0 on ARM).
|
||||||
//
|
// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
|
||||||
// TODO(1236026): This is a non-portable hack that should be removed.
|
// 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
|
#ifdef V8_HOST_ARCH_64_BIT
|
||||||
// Tested with GCC, not with MSVC.
|
|
||||||
struct ObjectPair {
|
struct ObjectPair {
|
||||||
Object* x;
|
Object* x;
|
||||||
Object* y;
|
Object* y;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline ObjectPair MakePair(Object* x, Object* y) {
|
static inline ObjectPair MakePair(Object* x, Object* y) {
|
||||||
ObjectPair result = {x, 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
|
#else
|
||||||
typedef uint64_t ObjectPair;
|
typedef uint64_t ObjectPair;
|
||||||
@ -4582,8 +4585,6 @@ static inline ObjectPair MakePair(Object* x, Object* y) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline Object* Unhole(Object* x, PropertyAttributes attributes) {
|
static inline Object* Unhole(Object* x, PropertyAttributes attributes) {
|
||||||
ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
|
ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
|
||||||
USE(attributes);
|
USE(attributes);
|
||||||
@ -7619,7 +7620,7 @@ static Object* Runtime_ListNatives(Arguments args) {
|
|||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
Handle<JSArray> result = Factory::NewJSArray(0);
|
Handle<JSArray> result = Factory::NewJSArray(0);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
#define ADD_ENTRY(Name, argc) \
|
#define ADD_ENTRY(Name, argc, ressize) \
|
||||||
{ \
|
{ \
|
||||||
HandleScope inner; \
|
HandleScope inner; \
|
||||||
Handle<String> name = \
|
Handle<String> name = \
|
||||||
@ -7655,13 +7656,13 @@ static Object* Runtime_IS_VAR(Arguments args) {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Implementation of Runtime
|
// Implementation of Runtime
|
||||||
|
|
||||||
#define F(name, nargs) \
|
#define F(name, nargs, ressize) \
|
||||||
{ #name, "RuntimeStub_" #name, FUNCTION_ADDR(Runtime_##name), nargs, \
|
{ #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[] = {
|
static Runtime::Function Runtime_functions[] = {
|
||||||
RUNTIME_FUNCTION_LIST(F)
|
RUNTIME_FUNCTION_LIST(F)
|
||||||
{ NULL, NULL, NULL, 0, -1 }
|
{ NULL, NULL, NULL, 0, -1, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef F
|
#undef F
|
||||||
|
405
src/runtime.h
405
src/runtime.h
@ -43,269 +43,269 @@ namespace internal {
|
|||||||
// this problem. Please avoid large recursive macros whenever possible.
|
// this problem. Please avoid large recursive macros whenever possible.
|
||||||
#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
|
#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
|
||||||
/* Property access */ \
|
/* Property access */ \
|
||||||
F(GetProperty, 2) \
|
F(GetProperty, 2, 1) \
|
||||||
F(KeyedGetProperty, 2) \
|
F(KeyedGetProperty, 2, 1) \
|
||||||
F(DeleteProperty, 2) \
|
F(DeleteProperty, 2, 1) \
|
||||||
F(HasLocalProperty, 2) \
|
F(HasLocalProperty, 2, 1) \
|
||||||
F(HasProperty, 2) \
|
F(HasProperty, 2, 1) \
|
||||||
F(HasElement, 2) \
|
F(HasElement, 2, 1) \
|
||||||
F(IsPropertyEnumerable, 2) \
|
F(IsPropertyEnumerable, 2, 1) \
|
||||||
F(GetPropertyNames, 1) \
|
F(GetPropertyNames, 1, 1) \
|
||||||
F(GetPropertyNamesFast, 1) \
|
F(GetPropertyNamesFast, 1, 1) \
|
||||||
F(GetArgumentsProperty, 1) \
|
F(GetArgumentsProperty, 1, 1) \
|
||||||
F(ToFastProperties, 1) \
|
F(ToFastProperties, 1, 1) \
|
||||||
F(ToSlowProperties, 1) \
|
F(ToSlowProperties, 1, 1) \
|
||||||
\
|
\
|
||||||
F(IsInPrototypeChain, 2) \
|
F(IsInPrototypeChain, 2, 1) \
|
||||||
F(SetHiddenPrototype, 2) \
|
F(SetHiddenPrototype, 2, 1) \
|
||||||
\
|
\
|
||||||
F(IsConstructCall, 0) \
|
F(IsConstructCall, 0, 1) \
|
||||||
\
|
\
|
||||||
/* Utilities */ \
|
/* Utilities */ \
|
||||||
F(GetCalledFunction, 0) \
|
F(GetCalledFunction, 0, 1) \
|
||||||
F(GetFunctionDelegate, 1) \
|
F(GetFunctionDelegate, 1, 1) \
|
||||||
F(GetConstructorDelegate, 1) \
|
F(GetConstructorDelegate, 1, 1) \
|
||||||
F(NewArguments, 1) \
|
F(NewArguments, 1, 1) \
|
||||||
F(NewArgumentsFast, 3) \
|
F(NewArgumentsFast, 3, 1) \
|
||||||
F(LazyCompile, 1) \
|
F(LazyCompile, 1, 1) \
|
||||||
F(SetNewFunctionAttributes, 1) \
|
F(SetNewFunctionAttributes, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Array join support */ \
|
/* Array join support */ \
|
||||||
F(PushIfAbsent, 2) \
|
F(PushIfAbsent, 2, 1) \
|
||||||
F(ArrayConcat, 1) \
|
F(ArrayConcat, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Conversions */ \
|
/* Conversions */ \
|
||||||
F(ToBool, 1) \
|
F(ToBool, 1, 1) \
|
||||||
F(Typeof, 1) \
|
F(Typeof, 1, 1) \
|
||||||
\
|
\
|
||||||
F(StringToNumber, 1) \
|
F(StringToNumber, 1, 1) \
|
||||||
F(StringFromCharCodeArray, 1) \
|
F(StringFromCharCodeArray, 1, 1) \
|
||||||
F(StringParseInt, 2) \
|
F(StringParseInt, 2, 1) \
|
||||||
F(StringParseFloat, 1) \
|
F(StringParseFloat, 1, 1) \
|
||||||
F(StringToLowerCase, 1) \
|
F(StringToLowerCase, 1, 1) \
|
||||||
F(StringToUpperCase, 1) \
|
F(StringToUpperCase, 1, 1) \
|
||||||
F(CharFromCode, 1) \
|
F(CharFromCode, 1, 1) \
|
||||||
F(URIEscape, 1) \
|
F(URIEscape, 1, 1) \
|
||||||
F(URIUnescape, 1) \
|
F(URIUnescape, 1, 1) \
|
||||||
\
|
\
|
||||||
F(NumberToString, 1) \
|
F(NumberToString, 1, 1) \
|
||||||
F(NumberToInteger, 1) \
|
F(NumberToInteger, 1, 1) \
|
||||||
F(NumberToJSUint32, 1) \
|
F(NumberToJSUint32, 1, 1) \
|
||||||
F(NumberToJSInt32, 1) \
|
F(NumberToJSInt32, 1, 1) \
|
||||||
F(NumberToSmi, 1) \
|
F(NumberToSmi, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Arithmetic operations */ \
|
/* Arithmetic operations */ \
|
||||||
F(NumberAdd, 2) \
|
F(NumberAdd, 2, 1) \
|
||||||
F(NumberSub, 2) \
|
F(NumberSub, 2, 1) \
|
||||||
F(NumberMul, 2) \
|
F(NumberMul, 2, 1) \
|
||||||
F(NumberDiv, 2) \
|
F(NumberDiv, 2, 1) \
|
||||||
F(NumberMod, 2) \
|
F(NumberMod, 2, 1) \
|
||||||
F(NumberUnaryMinus, 1) \
|
F(NumberUnaryMinus, 1, 1) \
|
||||||
\
|
\
|
||||||
F(StringAdd, 2) \
|
F(StringAdd, 2, 1) \
|
||||||
F(StringBuilderConcat, 2) \
|
F(StringBuilderConcat, 2, 1) \
|
||||||
\
|
\
|
||||||
/* Bit operations */ \
|
/* Bit operations */ \
|
||||||
F(NumberOr, 2) \
|
F(NumberOr, 2, 1) \
|
||||||
F(NumberAnd, 2) \
|
F(NumberAnd, 2, 1) \
|
||||||
F(NumberXor, 2) \
|
F(NumberXor, 2, 1) \
|
||||||
F(NumberNot, 1) \
|
F(NumberNot, 1, 1) \
|
||||||
\
|
\
|
||||||
F(NumberShl, 2) \
|
F(NumberShl, 2, 1) \
|
||||||
F(NumberShr, 2) \
|
F(NumberShr, 2, 1) \
|
||||||
F(NumberSar, 2) \
|
F(NumberSar, 2, 1) \
|
||||||
\
|
\
|
||||||
/* Comparisons */ \
|
/* Comparisons */ \
|
||||||
F(NumberEquals, 2) \
|
F(NumberEquals, 2, 1) \
|
||||||
F(StringEquals, 2) \
|
F(StringEquals, 2, 1) \
|
||||||
\
|
\
|
||||||
F(NumberCompare, 3) \
|
F(NumberCompare, 3, 1) \
|
||||||
F(SmiLexicographicCompare, 2) \
|
F(SmiLexicographicCompare, 2, 1) \
|
||||||
F(StringCompare, 2) \
|
F(StringCompare, 2, 1) \
|
||||||
\
|
\
|
||||||
/* Math */ \
|
/* Math */ \
|
||||||
F(Math_abs, 1) \
|
F(Math_abs, 1, 1) \
|
||||||
F(Math_acos, 1) \
|
F(Math_acos, 1, 1) \
|
||||||
F(Math_asin, 1) \
|
F(Math_asin, 1, 1) \
|
||||||
F(Math_atan, 1) \
|
F(Math_atan, 1, 1) \
|
||||||
F(Math_atan2, 2) \
|
F(Math_atan2, 2, 1) \
|
||||||
F(Math_ceil, 1) \
|
F(Math_ceil, 1, 1) \
|
||||||
F(Math_cos, 1) \
|
F(Math_cos, 1, 1) \
|
||||||
F(Math_exp, 1) \
|
F(Math_exp, 1, 1) \
|
||||||
F(Math_floor, 1) \
|
F(Math_floor, 1, 1) \
|
||||||
F(Math_log, 1) \
|
F(Math_log, 1, 1) \
|
||||||
F(Math_pow, 2) \
|
F(Math_pow, 2, 1) \
|
||||||
F(Math_round, 1) \
|
F(Math_round, 1, 1) \
|
||||||
F(Math_sin, 1) \
|
F(Math_sin, 1, 1) \
|
||||||
F(Math_sqrt, 1) \
|
F(Math_sqrt, 1, 1) \
|
||||||
F(Math_tan, 1) \
|
F(Math_tan, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Regular expressions */ \
|
/* Regular expressions */ \
|
||||||
F(RegExpCompile, 3) \
|
F(RegExpCompile, 3, 1) \
|
||||||
F(RegExpExec, 4) \
|
F(RegExpExec, 4, 1) \
|
||||||
\
|
\
|
||||||
/* Strings */ \
|
/* Strings */ \
|
||||||
F(StringCharCodeAt, 2) \
|
F(StringCharCodeAt, 2, 1) \
|
||||||
F(StringIndexOf, 3) \
|
F(StringIndexOf, 3, 1) \
|
||||||
F(StringLastIndexOf, 3) \
|
F(StringLastIndexOf, 3, 1) \
|
||||||
F(StringLocaleCompare, 2) \
|
F(StringLocaleCompare, 2, 1) \
|
||||||
F(StringSlice, 3) \
|
F(StringSlice, 3, 1) \
|
||||||
F(StringReplaceRegExpWithString, 4) \
|
F(StringReplaceRegExpWithString, 4, 1) \
|
||||||
F(StringMatch, 3) \
|
F(StringMatch, 3, 1) \
|
||||||
\
|
\
|
||||||
/* Numbers */ \
|
/* Numbers */ \
|
||||||
F(NumberToRadixString, 2) \
|
F(NumberToRadixString, 2, 1) \
|
||||||
F(NumberToFixed, 2) \
|
F(NumberToFixed, 2, 1) \
|
||||||
F(NumberToExponential, 2) \
|
F(NumberToExponential, 2, 1) \
|
||||||
F(NumberToPrecision, 2)
|
F(NumberToPrecision, 2, 1)
|
||||||
|
|
||||||
#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
|
#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
|
||||||
/* Reflection */ \
|
/* Reflection */ \
|
||||||
F(FunctionSetInstanceClassName, 2) \
|
F(FunctionSetInstanceClassName, 2, 1) \
|
||||||
F(FunctionSetLength, 2) \
|
F(FunctionSetLength, 2, 1) \
|
||||||
F(FunctionSetPrototype, 2) \
|
F(FunctionSetPrototype, 2, 1) \
|
||||||
F(FunctionGetName, 1) \
|
F(FunctionGetName, 1, 1) \
|
||||||
F(FunctionSetName, 2) \
|
F(FunctionSetName, 2, 1) \
|
||||||
F(FunctionGetSourceCode, 1) \
|
F(FunctionGetSourceCode, 1, 1) \
|
||||||
F(FunctionGetScript, 1) \
|
F(FunctionGetScript, 1, 1) \
|
||||||
F(FunctionGetScriptSourcePosition, 1) \
|
F(FunctionGetScriptSourcePosition, 1, 1) \
|
||||||
F(FunctionGetPositionForOffset, 2) \
|
F(FunctionGetPositionForOffset, 2, 1) \
|
||||||
F(FunctionIsAPIFunction, 1) \
|
F(FunctionIsAPIFunction, 1, 1) \
|
||||||
F(GetScript, 1) \
|
F(GetScript, 1, 1) \
|
||||||
F(CollectStackTrace, 2) \
|
F(CollectStackTrace, 2, 1) \
|
||||||
\
|
\
|
||||||
F(ClassOf, 1) \
|
F(ClassOf, 1, 1) \
|
||||||
F(SetCode, 2) \
|
F(SetCode, 2, 1) \
|
||||||
\
|
\
|
||||||
F(CreateApiFunction, 1) \
|
F(CreateApiFunction, 1, 1) \
|
||||||
F(IsTemplate, 1) \
|
F(IsTemplate, 1, 1) \
|
||||||
F(GetTemplateField, 2) \
|
F(GetTemplateField, 2, 1) \
|
||||||
F(DisableAccessChecks, 1) \
|
F(DisableAccessChecks, 1, 1) \
|
||||||
F(EnableAccessChecks, 1) \
|
F(EnableAccessChecks, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Dates */ \
|
/* Dates */ \
|
||||||
F(DateCurrentTime, 0) \
|
F(DateCurrentTime, 0, 1) \
|
||||||
F(DateParseString, 2) \
|
F(DateParseString, 2, 1) \
|
||||||
F(DateLocalTimezone, 1) \
|
F(DateLocalTimezone, 1, 1) \
|
||||||
F(DateLocalTimeOffset, 0) \
|
F(DateLocalTimeOffset, 0, 1) \
|
||||||
F(DateDaylightSavingsOffset, 1) \
|
F(DateDaylightSavingsOffset, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Numbers */ \
|
/* Numbers */ \
|
||||||
F(NumberIsFinite, 1) \
|
F(NumberIsFinite, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Globals */ \
|
/* Globals */ \
|
||||||
F(CompileString, 2) \
|
F(CompileString, 2, 1) \
|
||||||
F(GlobalPrint, 1) \
|
F(GlobalPrint, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Eval */ \
|
/* Eval */ \
|
||||||
F(GlobalReceiver, 1) \
|
F(GlobalReceiver, 1, 1) \
|
||||||
F(ResolvePossiblyDirectEval, 2) \
|
F(ResolvePossiblyDirectEval, 2, 1) \
|
||||||
\
|
\
|
||||||
F(SetProperty, -1 /* 3 or 4 */) \
|
F(SetProperty, -1 /* 3 or 4 */, 1) \
|
||||||
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */) \
|
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \
|
||||||
\
|
\
|
||||||
/* Arrays */ \
|
/* Arrays */ \
|
||||||
F(RemoveArrayHoles, 2) \
|
F(RemoveArrayHoles, 2, 1) \
|
||||||
F(GetArrayKeys, 2) \
|
F(GetArrayKeys, 2, 1) \
|
||||||
F(MoveArrayContents, 2) \
|
F(MoveArrayContents, 2, 1) \
|
||||||
F(EstimateNumberOfElements, 1) \
|
F(EstimateNumberOfElements, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Getters and Setters */ \
|
/* Getters and Setters */ \
|
||||||
F(DefineAccessor, -1 /* 4 or 5 */) \
|
F(DefineAccessor, -1 /* 4 or 5 */, 1) \
|
||||||
F(LookupAccessor, 3) \
|
F(LookupAccessor, 3, 1) \
|
||||||
\
|
\
|
||||||
/* Literals */ \
|
/* Literals */ \
|
||||||
F(MaterializeRegExpLiteral, 4)\
|
F(MaterializeRegExpLiteral, 4, 1)\
|
||||||
F(CreateArrayLiteralBoilerplate, 3) \
|
F(CreateArrayLiteralBoilerplate, 3, 1) \
|
||||||
F(CreateObjectLiteralBoilerplate, 3) \
|
F(CreateObjectLiteralBoilerplate, 3, 1) \
|
||||||
F(CloneLiteralBoilerplate, 1) \
|
F(CloneLiteralBoilerplate, 1, 1) \
|
||||||
F(CloneShallowLiteralBoilerplate, 1) \
|
F(CloneShallowLiteralBoilerplate, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Catch context extension objects */ \
|
/* Catch context extension objects */ \
|
||||||
F(CreateCatchExtensionObject, 2) \
|
F(CreateCatchExtensionObject, 2, 1) \
|
||||||
\
|
\
|
||||||
/* Statements */ \
|
/* Statements */ \
|
||||||
F(NewClosure, 2) \
|
F(NewClosure, 2, 1) \
|
||||||
F(NewObject, 1) \
|
F(NewObject, 1, 1) \
|
||||||
F(Throw, 1) \
|
F(Throw, 1, 1) \
|
||||||
F(ReThrow, 1) \
|
F(ReThrow, 1, 1) \
|
||||||
F(ThrowReferenceError, 1) \
|
F(ThrowReferenceError, 1, 1) \
|
||||||
F(StackGuard, 1) \
|
F(StackGuard, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Contexts */ \
|
/* Contexts */ \
|
||||||
F(NewContext, 1) \
|
F(NewContext, 1, 1) \
|
||||||
F(PushContext, 1) \
|
F(PushContext, 1, 1) \
|
||||||
F(PushCatchContext, 1) \
|
F(PushCatchContext, 1, 1) \
|
||||||
F(LookupContext, 2) \
|
F(LookupContext, 2, 1) \
|
||||||
F(LoadContextSlot, 2) \
|
F(LoadContextSlot, 2, 2) \
|
||||||
F(LoadContextSlotNoReferenceError, 2) \
|
F(LoadContextSlotNoReferenceError, 2, 2) \
|
||||||
F(StoreContextSlot, 3) \
|
F(StoreContextSlot, 3, 1) \
|
||||||
\
|
\
|
||||||
/* Declarations and initialization */ \
|
/* Declarations and initialization */ \
|
||||||
F(DeclareGlobals, 3) \
|
F(DeclareGlobals, 3, 1) \
|
||||||
F(DeclareContextSlot, 4) \
|
F(DeclareContextSlot, 4, 1) \
|
||||||
F(InitializeVarGlobal, -1 /* 1 or 2 */) \
|
F(InitializeVarGlobal, -1 /* 1 or 2 */, 1) \
|
||||||
F(InitializeConstGlobal, 2) \
|
F(InitializeConstGlobal, 2, 1) \
|
||||||
F(InitializeConstContextSlot, 3) \
|
F(InitializeConstContextSlot, 3, 1) \
|
||||||
F(OptimizeObjectForAddingMultipleProperties, 2) \
|
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
|
||||||
F(TransformToFastProperties, 1) \
|
F(TransformToFastProperties, 1, 1) \
|
||||||
\
|
\
|
||||||
/* Debugging */ \
|
/* Debugging */ \
|
||||||
F(DebugPrint, 1) \
|
F(DebugPrint, 1, 1) \
|
||||||
F(DebugTrace, 0) \
|
F(DebugTrace, 0, 1) \
|
||||||
F(TraceEnter, 0) \
|
F(TraceEnter, 0, 1) \
|
||||||
F(TraceExit, 1) \
|
F(TraceExit, 1, 1) \
|
||||||
F(Abort, 2) \
|
F(Abort, 2, 1) \
|
||||||
/* Logging */ \
|
/* Logging */ \
|
||||||
F(Log, 2) \
|
F(Log, 2, 1) \
|
||||||
\
|
\
|
||||||
/* Pseudo functions - handled as macros by parser */ \
|
/* Pseudo functions - handled as macros by parser */ \
|
||||||
F(IS_VAR, 1)
|
F(IS_VAR, 1, 1)
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||||
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
|
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
|
||||||
/* Debugger support*/ \
|
/* Debugger support*/ \
|
||||||
F(DebugBreak, 0) \
|
F(DebugBreak, 0, 1) \
|
||||||
F(SetDebugEventListener, 2) \
|
F(SetDebugEventListener, 2, 1) \
|
||||||
F(Break, 0) \
|
F(Break, 0, 1) \
|
||||||
F(DebugGetPropertyDetails, 2) \
|
F(DebugGetPropertyDetails, 2, 1) \
|
||||||
F(DebugGetProperty, 2) \
|
F(DebugGetProperty, 2, 1) \
|
||||||
F(DebugLocalPropertyNames, 1) \
|
F(DebugLocalPropertyNames, 1, 1) \
|
||||||
F(DebugLocalElementNames, 1) \
|
F(DebugLocalElementNames, 1, 1) \
|
||||||
F(DebugPropertyTypeFromDetails, 1) \
|
F(DebugPropertyTypeFromDetails, 1, 1) \
|
||||||
F(DebugPropertyAttributesFromDetails, 1) \
|
F(DebugPropertyAttributesFromDetails, 1, 1) \
|
||||||
F(DebugPropertyIndexFromDetails, 1) \
|
F(DebugPropertyIndexFromDetails, 1, 1) \
|
||||||
F(DebugInterceptorInfo, 1) \
|
F(DebugInterceptorInfo, 1, 1) \
|
||||||
F(DebugNamedInterceptorPropertyNames, 1) \
|
F(DebugNamedInterceptorPropertyNames, 1, 1) \
|
||||||
F(DebugIndexedInterceptorElementNames, 1) \
|
F(DebugIndexedInterceptorElementNames, 1, 1) \
|
||||||
F(DebugNamedInterceptorPropertyValue, 2) \
|
F(DebugNamedInterceptorPropertyValue, 2, 1) \
|
||||||
F(DebugIndexedInterceptorElementValue, 2) \
|
F(DebugIndexedInterceptorElementValue, 2, 1) \
|
||||||
F(CheckExecutionState, 1) \
|
F(CheckExecutionState, 1, 1) \
|
||||||
F(GetFrameCount, 1) \
|
F(GetFrameCount, 1, 1) \
|
||||||
F(GetFrameDetails, 2) \
|
F(GetFrameDetails, 2, 1) \
|
||||||
F(GetScopeCount, 2) \
|
F(GetScopeCount, 2, 1) \
|
||||||
F(GetScopeDetails, 3) \
|
F(GetScopeDetails, 3, 1) \
|
||||||
F(DebugPrintScopes, 0) \
|
F(DebugPrintScopes, 0, 1) \
|
||||||
F(GetCFrames, 1) \
|
F(GetCFrames, 1, 1) \
|
||||||
F(GetThreadCount, 1) \
|
F(GetThreadCount, 1, 1) \
|
||||||
F(GetThreadDetails, 2) \
|
F(GetThreadDetails, 2, 1) \
|
||||||
F(GetBreakLocations, 1) \
|
F(GetBreakLocations, 1, 1) \
|
||||||
F(SetFunctionBreakPoint, 3) \
|
F(SetFunctionBreakPoint, 3, 1) \
|
||||||
F(SetScriptBreakPoint, 3) \
|
F(SetScriptBreakPoint, 3, 1) \
|
||||||
F(ClearBreakPoint, 1) \
|
F(ClearBreakPoint, 1, 1) \
|
||||||
F(ChangeBreakOnException, 2) \
|
F(ChangeBreakOnException, 2, 1) \
|
||||||
F(PrepareStep, 3) \
|
F(PrepareStep, 3, 1) \
|
||||||
F(ClearStepping, 0) \
|
F(ClearStepping, 0, 1) \
|
||||||
F(DebugEvaluate, 4) \
|
F(DebugEvaluate, 4, 1) \
|
||||||
F(DebugEvaluateGlobal, 3) \
|
F(DebugEvaluateGlobal, 3, 1) \
|
||||||
F(DebugGetLoadedScripts, 0) \
|
F(DebugGetLoadedScripts, 0, 1) \
|
||||||
F(DebugReferencedBy, 3) \
|
F(DebugReferencedBy, 3, 1) \
|
||||||
F(DebugConstructedBy, 2) \
|
F(DebugConstructedBy, 2, 1) \
|
||||||
F(DebugGetPrototype, 1) \
|
F(DebugGetPrototype, 1, 1) \
|
||||||
F(SystemBreak, 0) \
|
F(SystemBreak, 0, 1) \
|
||||||
F(DebugDisassembleFunction, 1) \
|
F(DebugDisassembleFunction, 1, 1) \
|
||||||
F(DebugDisassembleConstructor, 1) \
|
F(DebugDisassembleConstructor, 1, 1) \
|
||||||
F(FunctionGetInferredName, 1)
|
F(FunctionGetInferredName, 1, 1)
|
||||||
#else
|
#else
|
||||||
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
|
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
|
||||||
#endif
|
#endif
|
||||||
@ -313,7 +313,7 @@ namespace internal {
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define RUNTIME_FUNCTION_LIST_DEBUG(F) \
|
#define RUNTIME_FUNCTION_LIST_DEBUG(F) \
|
||||||
/* Testing */ \
|
/* Testing */ \
|
||||||
F(ListNatives, 0)
|
F(ListNatives, 0, 1)
|
||||||
#else
|
#else
|
||||||
#define RUNTIME_FUNCTION_LIST_DEBUG(F)
|
#define RUNTIME_FUNCTION_LIST_DEBUG(F)
|
||||||
#endif
|
#endif
|
||||||
@ -336,7 +336,7 @@ namespace internal {
|
|||||||
class Runtime : public AllStatic {
|
class Runtime : public AllStatic {
|
||||||
public:
|
public:
|
||||||
enum FunctionId {
|
enum FunctionId {
|
||||||
#define F(name, nargs) k##name,
|
#define F(name, nargs, ressize) k##name,
|
||||||
RUNTIME_FUNCTION_LIST(F)
|
RUNTIME_FUNCTION_LIST(F)
|
||||||
kNofFunctions
|
kNofFunctions
|
||||||
#undef F
|
#undef F
|
||||||
@ -357,6 +357,9 @@ class Runtime : public AllStatic {
|
|||||||
// arguments.
|
// arguments.
|
||||||
int nargs;
|
int nargs;
|
||||||
int stub_id;
|
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.
|
// Get the runtime function with the given function id.
|
||||||
|
@ -541,7 +541,7 @@ void ExternalReferenceTable::PopulateTable() {
|
|||||||
#undef DEF_ENTRY_A
|
#undef DEF_ENTRY_A
|
||||||
|
|
||||||
// Runtime functions
|
// Runtime functions
|
||||||
#define RUNTIME_ENTRY(name, nargs) \
|
#define RUNTIME_ENTRY(name, nargs, ressize) \
|
||||||
{ RUNTIME_FUNCTION, \
|
{ RUNTIME_FUNCTION, \
|
||||||
Runtime::k##name, \
|
Runtime::k##name, \
|
||||||
"Runtime::" #name },
|
"Runtime::" #name },
|
||||||
|
@ -44,7 +44,7 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
|
|||||||
// rax, but JumpToBuiltin expects rax to contain the number of
|
// rax, but JumpToBuiltin expects rax to contain the number of
|
||||||
// arguments including the receiver.
|
// arguments including the receiver.
|
||||||
__ incq(rax);
|
__ incq(rax);
|
||||||
__ JumpToBuiltin(ExternalReference(id));
|
__ JumpToBuiltin(ExternalReference(id), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6829,7 +6829,8 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Do the runtime call to allocate the arguments object.
|
// Do the runtime call to allocate the arguments object.
|
||||||
__ bind(&runtime);
|
__ 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.
|
__ pop(rbx); // Return address.
|
||||||
__ push(rdx);
|
__ push(rdx);
|
||||||
__ push(rbx);
|
__ 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) {
|
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
||||||
// Check that stack should contain next handler, frame pointer, state and
|
// Check that stack should contain next handler, frame pointer, state and
|
||||||
// return address in that order.
|
// 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.
|
// Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
|
||||||
__ movq(Operand(rsp, 4 * kPointerSize), r14); // argc.
|
__ movq(Operand(rsp, 4 * kPointerSize), r14); // argc.
|
||||||
__ movq(Operand(rsp, 5 * kPointerSize), r15); // argv.
|
__ movq(Operand(rsp, 5 * kPointerSize), r15); // argv.
|
||||||
// Pass a pointer to the Arguments object as the first argument.
|
if (result_size_ < 2) {
|
||||||
__ lea(rcx, Operand(rsp, 4 * kPointerSize));
|
// 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)
|
#else // ! defined(_WIN64)
|
||||||
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
|
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
|
||||||
__ movq(rdi, r14); // argc.
|
__ movq(rdi, r14); // argc.
|
||||||
@ -7010,7 +7040,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
|
|||||||
__ j(zero, &failure_returned);
|
__ j(zero, &failure_returned);
|
||||||
|
|
||||||
// Exit the JavaScript to C++ exit frame.
|
// Exit the JavaScript to C++ exit frame.
|
||||||
__ LeaveExitFrame(frame_type);
|
__ LeaveExitFrame(frame_type, result_size_);
|
||||||
__ ret(0);
|
__ ret(0);
|
||||||
|
|
||||||
// Handling of failure.
|
// Handling of failure.
|
||||||
@ -7146,7 +7176,7 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
|
|||||||
StackFrame::EXIT;
|
StackFrame::EXIT;
|
||||||
|
|
||||||
// Enter the exit frame that transitions from JavaScript to C++.
|
// 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.
|
// rax: Holds the context at this point, but should not be used.
|
||||||
// On entry to code generated by GenerateCore, it must hold
|
// On entry to code generated by GenerateCore, it must hold
|
||||||
@ -7333,7 +7363,8 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
|||||||
__ push(rax);
|
__ push(rax);
|
||||||
|
|
||||||
// Do tail-call to runtime routine.
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm,
|
|||||||
__ push(rbx); // return address
|
__ push(rbx); // return address
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// 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
|
__ push(rcx); // return address
|
||||||
|
|
||||||
// Do tail-call to runtime routine.
|
// 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.
|
// Do tail-call to runtime routine.
|
||||||
__ TailCallRuntime(
|
__ 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(rax);
|
||||||
__ push(rcx);
|
__ push(rcx);
|
||||||
// Do tail-call to runtime routine.
|
// 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
|
// Extra capacity case: Check if there is extra capacity to
|
||||||
@ -532,7 +532,7 @@ void CallIC::Generate(MacroAssembler* masm,
|
|||||||
__ push(rbx);
|
__ push(rbx);
|
||||||
|
|
||||||
// Call the entry.
|
// Call the entry.
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
__ movq(rax, Immediate(2));
|
__ movq(rax, Immediate(2));
|
||||||
__ movq(rbx, f);
|
__ movq(rbx, f);
|
||||||
__ CallStub(&stub);
|
__ CallStub(&stub);
|
||||||
@ -763,7 +763,7 @@ void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
|
|||||||
__ push(rbx); // return address
|
__ push(rbx); // return address
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// 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
|
__ push(rbx); // return address
|
||||||
|
|
||||||
// Perform tail call to the entry.
|
// Perform tail call to the entry.
|
||||||
__ TailCallRuntime(f, 3);
|
__ TailCallRuntime(f, 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||||
@ -959,7 +959,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Perform tail call to the entry.
|
// Perform tail call to the entry.
|
||||||
__ TailCallRuntime(
|
__ TailCallRuntime(
|
||||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
|
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
|
||||||
|
@ -318,7 +318,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
|
|||||||
|
|
||||||
|
|
||||||
void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
|
void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
|
||||||
int num_arguments) {
|
int num_arguments,
|
||||||
|
int result_size) {
|
||||||
// ----------- S t a t e -------------
|
// ----------- S t a t e -------------
|
||||||
// -- rsp[0] : return address
|
// -- rsp[0] : return address
|
||||||
// -- rsp[8] : argument num_arguments - 1
|
// -- 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
|
// should remove this need and make the runtime routine entry code
|
||||||
// smarter.
|
// smarter.
|
||||||
movq(rax, Immediate(num_arguments));
|
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.
|
// Set the entry point and jump to the C entry runtime stub.
|
||||||
movq(rbx, ext);
|
movq(rbx, ext);
|
||||||
CEntryStub ces;
|
CEntryStub ces(result_size);
|
||||||
movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET);
|
movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
jmp(kScratchRegister);
|
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);
|
ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
|
||||||
|
|
||||||
// Setup the frame structure on the stack.
|
// Setup the frame structure on the stack.
|
||||||
@ -1016,6 +1018,21 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
// Get the required frame alignment for the OS.
|
||||||
static const int kFrameAlignment = OS::ActivationFrameAlignment();
|
static const int kFrameAlignment = OS::ActivationFrameAlignment();
|
||||||
if (kFrameAlignment > 0) {
|
if (kFrameAlignment > 0) {
|
||||||
@ -1024,30 +1041,19 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
|
|||||||
and_(rsp, kScratchRegister);
|
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.
|
// Patch the saved entry sp.
|
||||||
movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
|
movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
|
void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) {
|
||||||
// Registers:
|
// Registers:
|
||||||
// r15 : argv
|
// r15 : argv
|
||||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||||
// Restore the memory copy of the registers by digging them out from
|
// Restore the memory copy of the registers by digging them out from
|
||||||
// the stack. This is needed to allow nested break points.
|
// the stack. This is needed to allow nested break points.
|
||||||
if (type == StackFrame::EXIT_DEBUG) {
|
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.
|
// the function pointer after this.
|
||||||
const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;
|
const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;
|
||||||
int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;
|
int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;
|
||||||
@ -1060,7 +1066,18 @@ void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
|
|||||||
movq(rcx, Operand(rbp, 1 * kPointerSize));
|
movq(rcx, Operand(rbp, 1 * kPointerSize));
|
||||||
movq(rbp, Operand(rbp, 0 * 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));
|
lea(rsp, Operand(r15, 1 * kPointerSize));
|
||||||
|
|
||||||
// Restore current context from top and clear it in debug mode.
|
// Restore current context from top and clear it in debug mode.
|
||||||
|
@ -87,15 +87,15 @@ class MacroAssembler: public Assembler {
|
|||||||
void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
|
void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
|
||||||
|
|
||||||
// Enter specific kind of exit frame; either EXIT or
|
// Enter specific kind of exit frame; either EXIT or
|
||||||
// EXIT_DEBUG. Expects the number of arguments in register eax and
|
// EXIT_DEBUG. Expects the number of arguments in register rax and
|
||||||
// sets up the number of arguments in register edi and the pointer
|
// sets up the number of arguments in register rdi and the pointer
|
||||||
// to the first argument in register esi.
|
// to the first argument in register rsi.
|
||||||
void EnterExitFrame(StackFrame::Type type);
|
void EnterExitFrame(StackFrame::Type type, int result_size = 1);
|
||||||
|
|
||||||
// Leave the current exit frame. Expects the return value in
|
// Leave the current exit frame. Expects/provides the return value in
|
||||||
// register eax:edx (untouched) and the pointer to the first
|
// register rax:rdx (untouched) and the pointer to the first
|
||||||
// argument in register esi.
|
// argument in register rsi.
|
||||||
void LeaveExitFrame(StackFrame::Type type);
|
void LeaveExitFrame(StackFrame::Type type, int result_size = 1);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -298,10 +298,12 @@ class MacroAssembler: public Assembler {
|
|||||||
// Tail call of a runtime routine (jump).
|
// Tail call of a runtime routine (jump).
|
||||||
// Like JumpToBuiltin, but also takes care of passing the number
|
// Like JumpToBuiltin, but also takes care of passing the number
|
||||||
// of arguments.
|
// 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.
|
// Jump to the builtin routine.
|
||||||
void JumpToBuiltin(const ExternalReference& ext);
|
void JumpToBuiltin(const ExternalReference& ext, int result_size);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -612,7 +612,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|||||||
// MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
|
// MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
|
||||||
// Store register parameters in pre-allocated stack slots,
|
// Store register parameters in pre-allocated stack slots,
|
||||||
__ movq(Operand(rbp, kInputString), rcx);
|
__ 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, kInputStart), r8);
|
||||||
__ movq(Operand(rbp, kInputEnd), r9);
|
__ movq(Operand(rbp, kInputEnd), r9);
|
||||||
// Callee-save on Win64.
|
// Callee-save on Win64.
|
||||||
|
@ -354,7 +354,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
|
|||||||
__ movq(rax, Immediate(5));
|
__ movq(rax, Immediate(5));
|
||||||
__ movq(rbx, ref);
|
__ movq(rbx, ref);
|
||||||
|
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
__ CallStub(&stub);
|
__ CallStub(&stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
|||||||
|
|
||||||
ExternalReference ref =
|
ExternalReference ref =
|
||||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||||
__ TailCallRuntime(ref, 5);
|
__ TailCallRuntime(ref, 5, 1);
|
||||||
|
|
||||||
__ bind(&cleanup);
|
__ bind(&cleanup);
|
||||||
__ pop(scratch1);
|
__ pop(scratch1);
|
||||||
@ -511,7 +511,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
|||||||
|
|
||||||
ExternalReference ref = ExternalReference(
|
ExternalReference ref = ExternalReference(
|
||||||
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
||||||
__ TailCallRuntime(ref, 5);
|
__ TailCallRuntime(ref, 5, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -661,7 +661,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|||||||
__ movq(rax, Immediate(5));
|
__ movq(rax, Immediate(5));
|
||||||
__ movq(rbx, ref);
|
__ movq(rbx, ref);
|
||||||
|
|
||||||
CEntryStub stub;
|
CEntryStub stub(1);
|
||||||
__ CallStub(&stub);
|
__ CallStub(&stub);
|
||||||
|
|
||||||
__ LeaveInternalFrame();
|
__ LeaveInternalFrame();
|
||||||
@ -1362,7 +1362,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
|
|||||||
// Do tail-call to the runtime system.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference store_callback_property =
|
ExternalReference store_callback_property =
|
||||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
||||||
__ TailCallRuntime(store_callback_property, 4);
|
__ TailCallRuntime(store_callback_property, 4, 1);
|
||||||
|
|
||||||
// Handle store cache miss.
|
// Handle store cache miss.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
@ -1450,7 +1450,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
|
|||||||
// Do tail-call to the runtime system.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference store_ic_property =
|
ExternalReference store_ic_property =
|
||||||
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
||||||
__ TailCallRuntime(store_ic_property, 3);
|
__ TailCallRuntime(store_ic_property, 3, 1);
|
||||||
|
|
||||||
// Handle store cache miss.
|
// Handle store cache miss.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
@ -1652,7 +1652,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
|
|||||||
// Do tail-call to the runtime system.
|
// Do tail-call to the runtime system.
|
||||||
ExternalReference load_callback_property =
|
ExternalReference load_callback_property =
|
||||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||||
__ TailCallRuntime(load_callback_property, 5);
|
__ TailCallRuntime(load_callback_property, 5, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user