Port function call type-feedback cells to x64 and ARM.
R=fschneider@chromium.org BUG=v8:1857,v8:2079 Review URL: https://chromiumcodereview.appspot.com/10124008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11391 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
0556f87851
commit
60863e5cd6
@ -5169,9 +5169,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
__ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
|
||||
__ b(ne, &call);
|
||||
// Patch the receiver on the stack with the global receiver object.
|
||||
__ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
|
||||
__ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
|
||||
__ str(r2, MemOperand(sp, argc_ * kPointerSize));
|
||||
__ ldr(r3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
|
||||
__ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalReceiverOffset));
|
||||
__ str(r3, MemOperand(sp, argc_ * kPointerSize));
|
||||
__ bind(&call);
|
||||
}
|
||||
|
||||
@ -5179,9 +5179,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
// r1: pushed function (to be verified)
|
||||
__ JumpIfSmi(r1, &non_function);
|
||||
// Get the map of the function object.
|
||||
__ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
|
||||
__ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
|
||||
__ b(ne, &slow);
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
GenerateRecordCallTarget(masm);
|
||||
}
|
||||
|
||||
// Fast-case: Invoke the function now.
|
||||
// r1: pushed function
|
||||
ParameterCount actual(argc_);
|
||||
@ -5205,8 +5209,17 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
// Slow-case: Non-function called.
|
||||
__ bind(&slow);
|
||||
if (RecordCallTarget()) {
|
||||
// If there is a call target cache, mark it megamorphic in the
|
||||
// non-function case. MegamorphicSentinel is an immortal immovable
|
||||
// object (undefined) so no write barrier is needed.
|
||||
ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
|
||||
masm->isolate()->heap()->undefined_value());
|
||||
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
|
||||
__ str(ip, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
|
||||
}
|
||||
// Check for function proxy.
|
||||
__ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE));
|
||||
__ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE));
|
||||
__ b(ne, &non_function);
|
||||
__ push(r1); // put proxy as additional argument
|
||||
__ mov(r0, Operand(argc_ + 1, RelocInfo::NONE));
|
||||
|
@ -2361,6 +2361,18 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
}
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
|
||||
// Record call targets in unoptimized code, but not in the snapshot.
|
||||
if (!Serializer::enabled()) {
|
||||
flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->id(), cell);
|
||||
__ mov(r2, Operand(cell));
|
||||
}
|
||||
|
||||
CallFunctionStub stub(arg_count, flags);
|
||||
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
|
@ -3628,8 +3628,9 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
||||
|
||||
|
||||
void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
// rdi : the function to call
|
||||
// rbx : cache cell for call target
|
||||
// rdi : the function to call
|
||||
Isolate* isolate = masm->isolate();
|
||||
Label slow, non_function;
|
||||
|
||||
// The receiver might implicitly be the global object. This is
|
||||
@ -3644,9 +3645,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
__ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
|
||||
__ j(not_equal, &call, Label::kNear);
|
||||
// Patch the receiver on the stack with the global receiver object.
|
||||
__ movq(rbx, GlobalObjectOperand());
|
||||
__ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
|
||||
__ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rbx);
|
||||
__ movq(rcx, GlobalObjectOperand());
|
||||
__ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
|
||||
__ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx);
|
||||
__ bind(&call);
|
||||
}
|
||||
|
||||
@ -3656,6 +3657,10 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
__ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
|
||||
__ j(not_equal, &slow);
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
GenerateRecordCallTarget(masm);
|
||||
}
|
||||
|
||||
// Fast-case: Just invoke the function.
|
||||
ParameterCount actual(argc_);
|
||||
|
||||
@ -3678,6 +3683,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
// Slow-case: Non-function called.
|
||||
__ bind(&slow);
|
||||
if (RecordCallTarget()) {
|
||||
// If there is a call target cache, mark it megamorphic in the
|
||||
// non-function case. MegamorphicSentinel is an immortal immovable
|
||||
// object (undefined) so no write barrier is needed.
|
||||
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
TypeFeedbackCells::MegamorphicSentinel(isolate));
|
||||
}
|
||||
// Check for function proxy.
|
||||
__ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
|
||||
__ j(not_equal, &non_function);
|
||||
|
@ -2273,6 +2273,18 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
|
||||
}
|
||||
// Record source position for debugger.
|
||||
SetSourcePosition(expr->position());
|
||||
|
||||
// Record call targets in unoptimized code, but not in the snapshot.
|
||||
if (!Serializer::enabled()) {
|
||||
flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
|
||||
Handle<Object> uninitialized =
|
||||
TypeFeedbackCells::UninitializedSentinel(isolate());
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
|
||||
RecordTypeFeedbackCell(expr->id(), cell);
|
||||
__ Move(rbx, cell);
|
||||
}
|
||||
|
||||
CallFunctionStub stub(arg_count, flags);
|
||||
__ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
|
||||
__ CallStub(&stub);
|
||||
|
Loading…
Reference in New Issue
Block a user