Skip to content

Commit

Permalink
Revert of Add script context with context-allocated "const this" (pat…
Browse files Browse the repository at this point in the history
…chset #7 id:120001 of https://codereview.chromium.org/1179893002/)

Reason for revert:
[Sheriff] Breaks gc mole:
http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20gcmole/builds/2435

Original issue's description:
> Add script context with context-allocated "const this"
>
> R=rossberg@chromium.org
> LOG=N
> BUG=498811
>
> Committed: https://crrev.com/fa32d461c16a053cc6d48d3fb326016bc2765765
> Cr-Commit-Position: refs/heads/master@{#28988}

TBR=rossberg@chromium.org,mstarzinger@chromium.org,wingo@igalia.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=498811

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

Cr-Commit-Position: refs/heads/master@{#28992}
  • Loading branch information
mi-ac authored and Commit bot committed Jun 12, 2015
1 parent 74534bb commit 32e6455
Show file tree
Hide file tree
Showing 19 changed files with 204 additions and 259 deletions.
36 changes: 22 additions & 14 deletions src/arm/full-codegen-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3104,15 +3104,20 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {


void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
// r4: copy of the first argument or undefined if it doesn't exist.
// r5: copy of the first argument or undefined if it doesn't exist.
if (arg_count > 0) {
__ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
__ ldr(r5, MemOperand(sp, arg_count * kPointerSize));
} else {
__ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
}

// r4: the receiver of the enclosing function.
__ ldr(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));

// r3: the receiver of the enclosing function.
__ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
Variable* this_var = scope()->LookupThis();
DCHECK_NOT_NULL(this_var);
__ ldr(r3, VarOperand(this_var, r3));

// r2: language mode.
__ mov(r2, Operand(Smi::FromInt(language_mode())));
Expand All @@ -3121,8 +3126,9 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
__ mov(r1, Operand(Smi::FromInt(scope()->start_position())));

// Do the runtime call.
__ Push(r5);
__ Push(r4, r3, r2, r1);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
}


Expand Down Expand Up @@ -3154,9 +3160,10 @@ void FullCodeGenerator::VisitCall(Call* expr) {
Call::CallType call_type = expr->GetCallType(isolate());

if (call_type == Call::POSSIBLY_EVAL_CALL) {
// In a call to eval, we first call
// RuntimeHidden_asResolvePossiblyDirectEval to resolve the function we need
// to call. Then we call the resolved function using the given arguments.
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
// to resolve the function we need to call and the receiver of the
// call. Then we call the resolved function using the given
// arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();

Expand All @@ -3176,8 +3183,10 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ push(r1);
EmitResolvePossiblyDirectEval(arg_count);

// Touch up the stack with the resolved function.
// The runtime call returns a pair of values in r0 (function) and
// r1 (receiver). Touch up the stack with the right values.
__ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ str(r1, MemOperand(sp, arg_count * kPointerSize));

PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
}
Expand Down Expand Up @@ -4774,10 +4783,9 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
context()->Plug(r0);
} else if (proxy != NULL) {
Variable* var = proxy->var();
// Delete of an unqualified identifier is disallowed in strict mode but
// "delete this" is allowed.
bool is_this = var->HasThisName(isolate());
DCHECK(is_sloppy(language_mode()) || is_this);
// Delete of an unqualified identifier is disallowed in strict mode
// but "delete this" is allowed.
DCHECK(is_sloppy(language_mode()) || var->is_this());
if (var->IsUnallocated()) {
__ ldr(r2, GlobalObjectOperand());
__ mov(r1, Operand(var->name()));
Expand All @@ -4788,7 +4796,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
} else if (var->IsStackAllocated() || var->IsContextSlot()) {
// Result of deleting non-global, non-dynamic variables is false.
// The subexpression does not have side effects.
context()->Plug(is_this);
context()->Plug(var->is_this());
} else {
// Non-global variable. Call the runtime to try to delete from the
// context where the variable was introduced.
Expand Down
31 changes: 18 additions & 13 deletions src/arm64/full-codegen-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2799,17 +2799,21 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
}

__ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
// Prepare to push the receiver of the enclosing function.
Variable* this_var = scope()->LookupThis();
DCHECK_NOT_NULL(this_var);
__ Ldr(x11, VarOperand(this_var, x11));

// Prepare to push the language mode.
__ Mov(x11, Smi::FromInt(language_mode()));
__ Mov(x12, Smi::FromInt(language_mode()));
// Prepare to push the start position of the scope the calls resides in.
__ Mov(x12, Smi::FromInt(scope()->start_position()));
__ Mov(x13, Smi::FromInt(scope()->start_position()));

// Push.
__ Push(x9, x10, x11, x12);
__ Push(x9, x10, x11, x12, x13);

// Do the runtime call.
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
}


Expand Down Expand Up @@ -2841,8 +2845,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {

if (call_type == Call::POSSIBLY_EVAL_CALL) {
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
// to resolve the function we need to call. Then we call the resolved
// function using the given arguments.
// to resolve the function we need to call and the receiver of the
// call. Then we call the resolved function using the given
// arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();

Expand All @@ -2863,8 +2868,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ Push(x10);
EmitResolvePossiblyDirectEval(arg_count);

// Touch up the stack with the resolved function.
__ Poke(x0, (arg_count + 1) * kPointerSize);
// The runtime call returns a pair of values in x0 (function) and
// x1 (receiver). Touch up the stack with the right values.
__ PokePair(x1, x0, arg_count * kPointerSize);

PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
}
Expand Down Expand Up @@ -4458,10 +4464,9 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
context()->Plug(x0);
} else if (proxy != NULL) {
Variable* var = proxy->var();
// Delete of an unqualified identifier is disallowed in strict mode but
// "delete this" is allowed.
bool is_this = var->HasThisName(isolate());
DCHECK(is_sloppy(language_mode()) || is_this);
// Delete of an unqualified identifier is disallowed in strict mode
// but "delete this" is allowed.
DCHECK(is_sloppy(language_mode()) || var->is_this());
if (var->IsUnallocated()) {
__ Ldr(x12, GlobalObjectMemOperand());
__ Mov(x11, Operand(var->name()));
Expand All @@ -4472,7 +4477,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
} else if (var->IsStackAllocated() || var->IsContextSlot()) {
// Result of deleting non-global, non-dynamic variables is false.
// The subexpression does not have side effects.
context()->Plug(is_this);
context()->Plug(var->is_this());
} else {
// Non-global variable. Call the runtime to try to delete from the
// context where the variable was introduced.
Expand Down
41 changes: 0 additions & 41 deletions src/bootstrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,6 @@ class Genesis BASE_EMBEDDED {
// other objects in the snapshot.
void HookUpGlobalObject(Handle<GlobalObject> global_object,
Handle<FixedArray> outdated_contexts);
// The native context has a ScriptContextTable that store declarative bindings
// made in script scopes. Add a "this" binding to that table pointing to the
// global proxy.
void InstallGlobalThisBinding();
void HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts);
// New context initialization. Used for creating a context from scratch.
void InitializeGlobal(Handle<GlobalObject> global_object,
Handle<JSFunction> empty_function);
Expand Down Expand Up @@ -819,40 +814,6 @@ void Genesis::CreateRoots() {
}


void Genesis::InstallGlobalThisBinding() {
Handle<ScriptContextTable> script_contexts(
native_context()->script_context_table());
Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate());
Handle<JSFunction> closure(native_context()->closure());
Handle<Context> context = factory()->NewScriptContext(closure, scope_info);

// Go ahead and hook it up while we're at it.
int slot = scope_info->ReceiverContextSlotIndex();
DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
context->set(slot, native_context()->global_proxy());

native_context()->set_script_context_table(
*ScriptContextTable::Extend(script_contexts, context));
}


void Genesis::HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts) {
// One of these contexts should be the one that declares the global "this"
// binding.
for (int i = 0; i < outdated_contexts->length(); ++i) {
Context* context = Context::cast(outdated_contexts->get(i));
if (context->IsScriptContext()) {
ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
int slot = scope_info->ReceiverContextSlotIndex();
if (slot >= 0) {
DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
context->set(slot, native_context()->global_proxy());
}
}
}
}


Handle<GlobalObject> Genesis::CreateNewGlobals(
v8::Handle<v8::ObjectTemplate> global_proxy_template,
Handle<JSGlobalProxy> global_proxy) {
Expand Down Expand Up @@ -1011,7 +972,6 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
Handle<ScriptContextTable> script_context_table =
factory->NewScriptContextTable();
native_context()->set_script_context_table(*script_context_table);
InstallGlobalThisBinding();

Handle<String> object_name = factory->Object_string();
JSObject::AddProperty(
Expand Down Expand Up @@ -3126,7 +3086,6 @@ Genesis::Genesis(Isolate* isolate,
HookUpGlobalObject(global_object, outdated_contexts);
native_context()->builtins()->set_global_proxy(
native_context()->global_proxy());
HookUpGlobalThisBinding(outdated_contexts);

if (!ConfigureGlobalObjects(global_proxy_template)) return;
} else {
Expand Down
39 changes: 28 additions & 11 deletions src/compiler/ast-graph-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2420,17 +2420,37 @@ void AstGraphBuilder::VisitCall(Call* expr) {
// Create node to ask for help resolving potential eval call. This will
// provide a fully resolved callee and the corresponding receiver.
Node* function = GetFunctionClosure();
// TODO(wingo): ResolvePossibleDirectEval doesn't really need a receiver,
// now that eval scopes don't have "this" declarations. Remove this hack
// once ResolvePossibleDirectEval changes.
Node* receiver;
{
Variable* variable = info()->scope()->LookupThis();
if (variable->IsStackAllocated()) {
receiver = environment()->Lookup(variable);
} else {
DCHECK(variable->IsContextSlot());
int depth = current_scope()->ContextChainLength(variable->scope());
bool immutable = variable->maybe_assigned() == kNotAssigned;
const Operator* op =
javascript()->LoadContext(depth, variable->index(), immutable);
receiver = NewNode(op, current_context());
}
}
Node* language = jsgraph()->Constant(language_mode());
Node* position = jsgraph()->Constant(current_scope()->start_position());
const Operator* op =
javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
Node* new_callee =
NewNode(op, callee, source, function, language, position);
PrepareFrameState(new_callee, expr->EvalOrLookupId(),
javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
Node* pair =
NewNode(op, callee, source, function, receiver, language, position);
PrepareFrameState(pair, expr->EvalOrLookupId(),
OutputFrameStateCombine::PokeAt(arg_count + 1));
Node* new_callee = NewNode(common()->Projection(0), pair);
Node* new_receiver = NewNode(common()->Projection(1), pair);

// Patch callee on the environment.
// Patch callee and receiver on the environment.
environment()->Poke(arg_count + 1, new_callee);
environment()->Poke(arg_count + 0, new_receiver);
}

// Create node to perform the function call.
Expand Down Expand Up @@ -2853,9 +2873,7 @@ void AstGraphBuilder::VisitDelete(UnaryOperation* expr) {
// Delete of an unqualified identifier is only allowed in classic mode but
// deleting "this" is allowed in all language modes.
Variable* variable = expr->expression()->AsVariableProxy()->var();
// Delete of an unqualified identifier is disallowed in strict mode but
// "delete this" is allowed.
DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate()));
DCHECK(is_sloppy(language_mode()) || variable->is_this());
value = BuildVariableDelete(variable, expr->id(),
ast_context()->GetStateCombine());
} else if (expr->expression()->IsProperty()) {
Expand Down Expand Up @@ -3303,10 +3321,9 @@ Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
}
case Variable::PARAMETER:
case Variable::LOCAL:
case Variable::CONTEXT: {
case Variable::CONTEXT:
// Local var, const, or let variable or context variable.
return jsgraph()->BooleanConstant(variable->HasThisName(isolate()));
}
return jsgraph()->BooleanConstant(variable->is_this());
case Variable::LOOKUP: {
// Dynamic lookup of context variable (anywhere in the chain).
Node* name = jsgraph()->Constant(variable->name());
Expand Down
11 changes: 6 additions & 5 deletions src/hydrogen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10197,11 +10197,12 @@ void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) {
if (var->IsUnallocated()) {
Bailout(kDeleteWithGlobalVariable);
} else if (var->IsStackAllocated() || var->IsContextSlot()) {
// Result of deleting non-global variables is false. 'this' is not really
// a variable, though we implement it as one. The subexpression does not
// have side effects.
HValue* value = var->HasThisName(isolate()) ? graph()->GetConstantTrue()
: graph()->GetConstantFalse();
// Result of deleting non-global variables is false. 'this' is not
// really a variable, though we implement it as one. The
// subexpression does not have side effects.
HValue* value = var->is_this()
? graph()->GetConstantTrue()
: graph()->GetConstantFalse();
return ast_context()->ReturnValue(value);
} else {
Bailout(kDeleteWithNonGlobalVariable);
Expand Down
24 changes: 14 additions & 10 deletions src/ia32/full-codegen-ia32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3006,15 +3006,18 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {

// Push the enclosing function.
__ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));

// Push the receiver of the enclosing function.
Variable* this_var = scope()->LookupThis();
DCHECK_NOT_NULL(this_var);
__ push(VarOperand(this_var, ecx));
// Push the language mode.
__ push(Immediate(Smi::FromInt(language_mode())));

// Push the start position of the scope the calls resides in.
__ push(Immediate(Smi::FromInt(scope()->start_position())));

// Do the runtime call.
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
}


Expand Down Expand Up @@ -3046,8 +3049,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {

if (call_type == Call::POSSIBLY_EVAL_CALL) {
// In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
// to resolve the function we need to call. Then we call the resolved
// function using the given arguments.
// to resolve the function we need to call and the receiver of the call.
// Then we call the resolved function using the given arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope pos_scope(masm()->positions_recorder());
Expand All @@ -3064,7 +3067,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
EmitResolvePossiblyDirectEval(arg_count);

// Touch up the stack with the resolved function.
// The runtime call returns a pair of values in eax (function) and
// edx (receiver). Touch up the stack with the right values.
__ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);

PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
Expand Down Expand Up @@ -4698,10 +4703,9 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
context()->Plug(eax);
} else if (proxy != NULL) {
Variable* var = proxy->var();
// Delete of an unqualified identifier is disallowed in strict mode but
// "delete this" is allowed.
bool is_this = var->HasThisName(isolate());
DCHECK(is_sloppy(language_mode()) || is_this);
// Delete of an unqualified identifier is disallowed in strict mode
// but "delete this" is allowed.
DCHECK(is_sloppy(language_mode()) || var->is_this());
if (var->IsUnallocated()) {
__ push(GlobalObjectOperand());
__ push(Immediate(var->name()));
Expand All @@ -4712,7 +4716,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
// Result of deleting non-global variables is false. 'this' is
// not really a variable, though we implement it as one. The
// subexpression does not have side effects.
context()->Plug(is_this);
context()->Plug(var->is_this());
} else {
// Non-global variable. Call the runtime to try to delete from the
// context where the variable was introduced.
Expand Down
Loading

0 comments on commit 32e6455

Please sign in to comment.