Remove receiver conversion from function prologue

Depends on https://codereview.chromium.org/1407373007/
After that CL, all receiver conversion is handled by the call builtin.

BUG=

Review URL: https://codereview.chromium.org/1414883011

Cr-Commit-Position: refs/heads/master@{#31826}
This commit is contained in:
verwaest 2015-11-05 05:23:13 -08:00 committed by Commit bot
parent faf0238b45
commit 4ab1b05d5e
17 changed files with 34 additions and 233 deletions

View File

@ -175,6 +175,8 @@ namespace internal {
V(kRegisterWasClobbered, "Register was clobbered") \
V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space") \
V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \
V(kSloppyFunctionExpectsJSReceiverReceiver, \
"Sloppy function expects JSReceiver as receiver.") \
V(kSmiAdditionOverflow, "Smi addition overflow") \
V(kSmiSubtractionOverflow, "Smi subtraction overflow") \
V(kSpread, "Spread in array literal") \

View File

@ -328,9 +328,8 @@ base::SmartArrayPointer<char> CompilationInfo::GetDebugName() const {
}
bool CompilationInfo::MustReplaceUndefinedReceiverWithGlobalProxy() {
return is_sloppy(language_mode()) && !is_native() &&
scope()->has_this_declaration() && scope()->receiver()->is_used();
bool CompilationInfo::ExpectsJSReceiverAsReceiver() {
return is_sloppy(language_mode()) && !is_native();
}

View File

@ -326,7 +326,7 @@ class CompilationInfo {
}
bool ShouldEnsureSpaceForLazyDeopt() { return !IsStub(); }
bool MustReplaceUndefinedReceiverWithGlobalProxy();
bool ExpectsJSReceiverAsReceiver();
// Determines whether or not to insert a self-optimization header.
bool ShouldSelfOptimize();

View File

@ -526,14 +526,6 @@ bool AstGraphBuilder::CreateGraph(bool stack_check) {
env.RawParameterBind(0, jsgraph()->TheHoleConstant());
}
// Build receiver check for sloppy mode if necessary.
// TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
if (scope->has_this_declaration()) {
Node* original_receiver = env.RawParameterLookup(0);
Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
env.RawParameterBind(0, patched_receiver);
}
// Build local context only if there are context allocated variables.
if (info()->num_heap_slots() > 0) {
// Push a new inner context scope for the current activation.
@ -3112,28 +3104,6 @@ Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
}
Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object). Otherwise there is nothing left to do here.
if (info()->MustReplaceUndefinedReceiverWithGlobalProxy()) {
IfBuilder receiver_check(this);
Node* undefined = jsgraph()->UndefinedConstant();
Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined);
receiver_check.If(check);
receiver_check.Then();
Node* proxy = BuildLoadGlobalProxy();
environment()->Push(proxy);
receiver_check.Else();
environment()->Push(receiver);
receiver_check.End();
return environment()->Pop();
} else {
return receiver;
}
}
Node* AstGraphBuilder::BuildLocalActivationContext(Node* context) {
Scope* scope = info()->scope();

View File

@ -242,9 +242,6 @@ class AstGraphBuilder : public AstVisitor {
// resulting node. The operand stack height remains the same, variables and
// other dependencies tracked by the environment might be mutated though.
// Builder to create a receiver check for sloppy mode.
Node* BuildPatchReceiverToGlobalProxy(Node* receiver);
// Builders to create local function, script and block contexts.
Node* BuildLocalActivationContext(Node* context);
Node* BuildLocalFunctionContext(Scope* scope);

View File

@ -115,24 +115,6 @@ bool LCodeGen::GeneratePrologue() {
// pp: Callee's constant pool pointer (if enabled)
// fp: Caller's frame pointer.
// lr: Caller's pc.
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info()->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
__ ldr(r2, MemOperand(sp, receiver_offset));
__ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
__ b(ne, &ok);
__ ldr(r2, GlobalObjectOperand());
__ ldr(r2, FieldMemOperand(r2, JSGlobalObject::kGlobalProxyOffset));
__ str(r2, MemOperand(sp, receiver_offset));
__ bind(&ok);
}
}
info()->set_prologue_offset(masm_->pc_offset());

View File

@ -628,22 +628,6 @@ bool LCodeGen::GeneratePrologue() {
__ Debug("stop-at", __LINE__, BREAK);
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info()->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
int receiver_offset = info_->scope()->num_parameters() * kXRegSize;
__ Peek(x10, receiver_offset);
__ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok);
__ Ldr(x10, GlobalObjectMemOperand());
__ Ldr(x10, FieldMemOperand(x10, JSGlobalObject::kGlobalProxyOffset));
__ Poke(x10, receiver_offset);
__ Bind(&ok);
}
}
DCHECK(__ StackPointer().Is(jssp));

View File

@ -138,26 +138,6 @@ bool LCodeGen::GeneratePrologue() {
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info()->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
// +1 for return address.
int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
__ mov(ecx, Operand(esp, receiver_offset));
__ cmp(ecx, isolate()->factory()->undefined_value());
__ j(not_equal, &ok, Label::kNear);
__ mov(ecx, GlobalObjectOperand());
__ mov(ecx, FieldOperand(ecx, JSGlobalObject::kGlobalProxyOffset));
__ mov(Operand(esp, receiver_offset), ecx);
__ bind(&ok);
}
if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
// Move state of dynamic frame alignment into edx.
__ Move(edx, Immediate(kNoAlignmentPadding));

View File

@ -138,24 +138,6 @@ bool LCodeGen::GeneratePrologue() {
// cp: Callee's context.
// fp: Caller's frame pointer.
// lr: Caller's pc.
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info()->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ lw(a2, MemOperand(sp, receiver_offset));
__ Branch(&ok, ne, a2, Operand(at));
__ lw(a2, GlobalObjectOperand());
__ lw(a2, FieldMemOperand(a2, JSGlobalObject::kGlobalProxyOffset));
__ sw(a2, MemOperand(sp, receiver_offset));
__ bind(&ok);
}
}
info()->set_prologue_offset(masm_->pc_offset());

View File

@ -113,24 +113,6 @@ bool LCodeGen::GeneratePrologue() {
// cp: Callee's context.
// fp: Caller's frame pointer.
// lr: Caller's pc.
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info()->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ ld(a2, MemOperand(sp, receiver_offset));
__ Branch(&ok, ne, a2, Operand(at));
__ ld(a2, GlobalObjectOperand());
__ ld(a2, FieldMemOperand(a2, JSGlobalObject::kGlobalProxyOffset));
__ sd(a2, MemOperand(sp, receiver_offset));
__ bind(&ok);
}
}
info()->set_prologue_offset(masm_->pc_offset());

View File

@ -125,24 +125,6 @@ bool LCodeGen::GeneratePrologue() {
__ int3();
}
#endif
// Sloppy mode functions need to replace the receiver with the global proxy
// when called as functions (without an explicit receiver object).
if (info()->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
StackArgumentsAccessor args(rsp, scope()->num_parameters());
__ movp(rcx, args.GetReceiverOperand());
__ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, &ok, Label::kNear);
__ movp(rcx, GlobalObjectOperand());
__ movp(rcx, FieldOperand(rcx, JSGlobalObject::kGlobalProxyOffset));
__ movp(args.GetReceiverOperand(), rcx);
__ bind(&ok);
}
}
info()->set_prologue_offset(masm_->pc_offset());

View File

@ -116,22 +116,12 @@ void FullCodeGenerator::Generate() {
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) {
int receiver_offset = info->scope()->num_parameters() * kPointerSize;
__ ldr(r2, MemOperand(sp, receiver_offset));
__ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
__ b(ne, &ok);
__ ldr(r2, GlobalObjectOperand());
__ ldr(r2, FieldMemOperand(r2, JSGlobalObject::kGlobalProxyOffset));
__ str(r2, MemOperand(sp, receiver_offset));
__ bind(&ok);
__ AssertNotSmi(r2);
__ CompareObjectType(r2, r2, no_reg, FIRST_SPEC_OBJECT_TYPE);
__ Assert(ge, kSloppyFunctionExpectsJSReceiverReceiver);
}
// Open a frame scope to indicate that there is a frame on the stack. The

View File

@ -115,23 +115,14 @@ void FullCodeGenerator::Generate() {
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) {
int receiver_offset = info->scope()->num_parameters() * kXRegSize;
__ Peek(x10, receiver_offset);
__ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok);
__ Ldr(x10, GlobalObjectMemOperand());
__ Ldr(x10, FieldMemOperand(x10, JSGlobalObject::kGlobalProxyOffset));
__ Poke(x10, receiver_offset);
__ Bind(&ok);
__ AssertNotSmi(x10);
__ CompareObjectType(x10, x10, x11, FIRST_SPEC_OBJECT_TYPE);
__ Assert(ge, kSloppyFunctionExpectsJSReceiverReceiver);
}
// Open a frame scope to indicate that there is a frame on the stack.
// The MANUAL indicates that the scope shouldn't actually generate code
// to set up the frame because we do it manually below.

View File

@ -105,24 +105,12 @@ void FullCodeGenerator::Generate() {
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
// +1 for return address.
if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) {
int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize;
__ mov(ecx, Operand(esp, receiver_offset));
__ cmp(ecx, isolate()->factory()->undefined_value());
__ j(not_equal, &ok, Label::kNear);
__ mov(ecx, GlobalObjectOperand());
__ mov(ecx, FieldOperand(ecx, JSGlobalObject::kGlobalProxyOffset));
__ mov(Operand(esp, receiver_offset), ecx);
__ bind(&ok);
__ AssertNotSmi(ecx);
__ CmpObjectType(ecx, FIRST_SPEC_OBJECT_TYPE, ecx);
__ Assert(above_equal, kSloppyFunctionExpectsJSReceiverReceiver);
}
// Open a frame scope to indicate that there is a frame on the stack. The

View File

@ -124,22 +124,13 @@ void FullCodeGenerator::Generate() {
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) {
int receiver_offset = info->scope()->num_parameters() * kPointerSize;
__ lw(at, MemOperand(sp, receiver_offset));
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
__ Branch(&ok, ne, a2, Operand(at));
__ lw(a2, GlobalObjectOperand());
__ lw(a2, FieldMemOperand(a2, JSGlobalObject::kGlobalProxyOffset));
__ sw(a2, MemOperand(sp, receiver_offset));
__ bind(&ok);
__ lw(a2, MemOperand(sp, receiver_offset));
__ AssertNotSmi(a2);
__ GetObjectType(a2, a2, a2);
__ Check(ge, kSloppyFunctionExpectsJSReceiverReceiver, a2,
Operand(FIRST_SPEC_OBJECT_TYPE));
}
// Open a frame scope to indicate that there is a frame on the stack. The

View File

@ -124,22 +124,15 @@ void FullCodeGenerator::Generate() {
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) {
int receiver_offset = info->scope()->num_parameters() * kPointerSize;
__ ld(at, MemOperand(sp, receiver_offset));
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
__ Branch(&ok, ne, a2, Operand(at));
__ ld(a2, GlobalObjectOperand());
__ ld(a2, FieldMemOperand(a2, JSGlobalObject::kGlobalProxyOffset));
__ sd(a2, MemOperand(sp, receiver_offset));
__ bind(&ok);
__ lw(a2, MemOperand(sp, receiver_offset));
__ AssertNotSmi(a2);
__ GetObjectType(a2, a2, a2);
__ Check(ge, kSloppyFunctionExpectsJSReceiverReceiver, a2,
Operand(FIRST_SPEC_OBJECT_TYPE));
}
// Open a frame scope to indicate that there is a frame on the stack. The
// MANUAL indicates that the scope shouldn't actually generate code to set up
// the frame (that is done below).

View File

@ -104,24 +104,12 @@ void FullCodeGenerator::Generate() {
}
#endif
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) {
Label ok;
// +1 for return address.
if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) {
StackArgumentsAccessor args(rsp, info->scope()->num_parameters());
__ movp(rcx, args.GetReceiverOperand());
__ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, &ok, Label::kNear);
__ movp(rcx, GlobalObjectOperand());
__ movp(rcx, FieldOperand(rcx, JSGlobalObject::kGlobalProxyOffset));
__ movp(args.GetReceiverOperand(), rcx);
__ bind(&ok);
__ AssertNotSmi(rcx);
__ CmpObjectType(rcx, FIRST_SPEC_OBJECT_TYPE, rcx);
__ Assert(above_equal, kSloppyFunctionExpectsJSReceiverReceiver);
}
// Open a frame scope to indicate that there is a frame on the stack. The