| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 3920)
|
| +++ src/ia32/codegen-ia32.cc (working copy)
|
| @@ -695,8 +695,10 @@
|
| // The expression is a variable proxy that does not rewrite to a
|
| // property. Global variables are treated as named property references.
|
| if (var->is_global()) {
|
| - // Named loads require object in eax. Named stores don't use references.
|
| - // Spilling eax makes it free, so LoadGlobal loads directly into eax.
|
| + // If eax is free, the register allocator prefers it. Thus the code
|
| + // generator will load the global object into eax, which is where
|
| + // LoadIC wants it. Most uses of Reference call LoadIC directly
|
| + // after the reference is created.
|
| frame_->Spill(eax);
|
| LoadGlobal();
|
| ref->set_type(Reference::NAMED);
|
| @@ -4316,6 +4318,10 @@
|
|
|
| // All extension objects were empty and it is safe to use a global
|
| // load IC call.
|
| + // The register allocator prefers eax if it is free, so the code generator
|
| + // will load the global object directly into eax, which is where the LoadIC
|
| + // expects it.
|
| + frame_->Spill(eax);
|
| LoadGlobal();
|
| frame_->Push(slot->var()->name());
|
| RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
|
| @@ -4601,8 +4607,8 @@
|
| // Duplicate the object as the IC receiver.
|
| frame_->Dup();
|
| Load(property->value());
|
| - frame_->Push(key);
|
| - Result ignored = frame_->CallStoreIC();
|
| + Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false);
|
| + dummy.Unuse();
|
| break;
|
| }
|
| // Fall through
|
| @@ -4776,10 +4782,9 @@
|
| bool is_trivial_receiver = false;
|
| if (var != NULL) {
|
| name = var->name();
|
| - LoadGlobal();
|
| } else {
|
| Literal* lit = prop->key()->AsLiteral();
|
| - ASSERT(lit != NULL);
|
| + ASSERT_NOT_NULL(lit);
|
| name = Handle<String>::cast(lit->handle());
|
| // Do not materialize the receiver on the frame if it is trivial.
|
| is_trivial_receiver = prop->obj()->IsTrivial();
|
| @@ -4787,6 +4792,7 @@
|
| }
|
|
|
| if (node->starts_initialization_block()) {
|
| + ASSERT_EQ(NULL, var);
|
| // Change to slow case in the beginning of an initialization block to
|
| // avoid the quadratic behavior of repeatedly adding fast properties.
|
| if (is_trivial_receiver) {
|
| @@ -4807,6 +4813,11 @@
|
| if (node->is_compound()) {
|
| if (is_trivial_receiver) {
|
| frame()->Push(prop->obj());
|
| + } else if (var != NULL) {
|
| + // The LoadIC stub expects the object in eax.
|
| + // Freeing eax causes the code generator to load the global into it.
|
| + frame_->Spill(eax);
|
| + LoadGlobal();
|
| } else {
|
| frame()->Dup();
|
| }
|
| @@ -4826,17 +4837,19 @@
|
|
|
| // Perform the assignment. It is safe to ignore constants here.
|
| ASSERT(var == NULL || var->mode() != Variable::CONST);
|
| - ASSERT(node->op() != Token::INIT_CONST);
|
| + ASSERT_NE(Token::INIT_CONST, node->op());
|
| if (is_trivial_receiver) {
|
| Result value = frame()->Pop();
|
| frame()->Push(prop->obj());
|
| frame()->Push(&value);
|
| }
|
| CodeForSourcePosition(node->position());
|
| - Result answer = EmitNamedStore(name);
|
| + bool is_contextual = (var != NULL);
|
| + Result answer = EmitNamedStore(name, is_contextual);
|
| frame()->Push(&answer);
|
|
|
| if (node->ends_initialization_block()) {
|
| + ASSERT_EQ(NULL, var);
|
| // The argument to the runtime call is the receiver.
|
| if (is_trivial_receiver) {
|
| frame()->Push(prop->obj());
|
| @@ -4851,7 +4864,7 @@
|
| Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
|
| }
|
|
|
| - ASSERT(frame()->height() == original_height + 1);
|
| + ASSERT_EQ(frame()->height(), original_height + 1);
|
| }
|
|
|
|
|
| @@ -4861,7 +4874,7 @@
|
| #endif
|
| Comment cmnt(masm_, "[ Named Property Assignment");
|
| Property* prop = node->target()->AsProperty();
|
| - ASSERT(prop != NULL);
|
| + ASSERT_NOT_NULL(prop);
|
|
|
| // Evaluate the receiver subexpression.
|
| Load(prop->obj());
|
| @@ -6779,14 +6792,13 @@
|
| }
|
|
|
|
|
| -Result CodeGenerator::EmitNamedStore(Handle<String> name) {
|
| +Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
|
| #ifdef DEBUG
|
| - int original_height = frame()->height();
|
| + int expected_height = frame()->height() - (is_contextual ? 1 : 2);
|
| #endif
|
| - frame()->Push(name);
|
| - Result result = frame()->CallStoreIC();
|
| + Result result = frame()->CallStoreIC(name, is_contextual);
|
|
|
| - ASSERT(frame()->height() == original_height - 2);
|
| + ASSERT_EQ(expected_height, frame()->height());
|
| return result;
|
| }
|
|
|
| @@ -7103,7 +7115,7 @@
|
|
|
| case NAMED: {
|
| Comment cmnt(masm, "[ Store to named Property");
|
| - Result answer = cgen_->EmitNamedStore(GetName());
|
| + Result answer = cgen_->EmitNamedStore(GetName(), false);
|
| cgen_->frame()->Push(&answer);
|
| set_unloaded();
|
| break;
|
|
|