Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Unified Diff: src/ia32/codegen-ia32.cc

Issue 650028: Improve stores to global variables. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/virtual-frame-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/virtual-frame-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698