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

Side by Side Diff: src/codegen-ia32.cc

Issue 20417: Experimental: eliminate a few spilled scopes in function prologue and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // needs to be copied into the context, it must be the last argument 184 // needs to be copied into the context, it must be the last argument
185 // passed to the parameter that needs to be copied. This is a rare 185 // passed to the parameter that needs to be copied. This is a rare
186 // case so we don't check for it, instead we rely on the copying 186 // case so we don't check for it, instead we rely on the copying
187 // order: such a parameter is copied repeatedly into the same 187 // order: such a parameter is copied repeatedly into the same
188 // context location and thus the last value is what is seen inside 188 // context location and thus the last value is what is seen inside
189 // the function. 189 // the function.
190 for (int i = 0; i < scope_->num_parameters(); i++) { 190 for (int i = 0; i < scope_->num_parameters(); i++) {
191 Variable* par = scope_->parameter(i); 191 Variable* par = scope_->parameter(i);
192 Slot* slot = par->slot(); 192 Slot* slot = par->slot();
193 if (slot != NULL && slot->type() == Slot::CONTEXT) { 193 if (slot != NULL && slot->type() == Slot::CONTEXT) {
194 VirtualFrame::SpilledScope spilled_scope(this); 194 // The use of SlotOperand below is safe in unspilled code
195 ASSERT(!scope_->is_global_scope()); // no parameters in global scope 195 // because the slot is guaranteed to be a context slot.
196 __ mov(eax, frame_->ParameterAt(i)); 196 //
197 // Loads ecx with context; used below in RecordWrite. 197 // There are no parameters in the global scope.
198 __ mov(SlotOperand(slot, edx), eax); 198 ASSERT(!scope_->is_global_scope());
199 frame_->PushParameterAt(i);
200 Result value = frame_->Pop();
201 value.ToRegister();
202
203 Result context = allocator_->Allocate();
204 ASSERT(context.is_valid());
205 // Loads the context register with the context, used below
William Hesse 2009/02/17 13:36:19 "SlotOperand loads context.reg() with the context
206 // in RecordWrite.
207 __ mov(SlotOperand(slot, context.reg()), value.reg());
199 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 208 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
200 __ RecordWrite(edx, offset, eax, ebx); 209 Result scratch = allocator_->Allocate();
210 ASSERT(scratch.is_valid());
211 frame_->Spill(context.reg());
212 frame_->Spill(value.reg());
213 __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
201 } 214 }
202 } 215 }
203 } 216 }
204 217
205 // This section stores the pointer to the arguments object that 218 // This section stores the pointer to the arguments object that
206 // was allocated and copied into above. If the address was not 219 // was allocated and copied into above. If the address was not
207 // saved to TOS, we push ecx onto the stack. 220 // saved to TOS, we push ecx onto the stack.
208 // 221 //
209 // Store the arguments object. This must happen after context 222 // Store the arguments object. This must happen after context
210 // initialization because the arguments object may be stored in the 223 // initialization because the arguments object may be stored in the
211 // context. 224 // context.
212 if (scope_->arguments() != NULL) { 225 if (scope_->arguments() != NULL) {
213 VirtualFrame::SpilledScope spilled_scope(this);
214 Comment cmnt(masm_, "[ store arguments object"); 226 Comment cmnt(masm_, "[ store arguments object");
215 { Reference shadow_ref(this, scope_->arguments_shadow()); 227 { Reference shadow_ref(this, scope_->arguments_shadow());
216 ASSERT(shadow_ref.is_slot()); 228 ASSERT(shadow_ref.is_slot());
217 { Reference arguments_ref(this, scope_->arguments()); 229 { Reference arguments_ref(this, scope_->arguments());
218 ASSERT(arguments_ref.is_slot()); 230 ASSERT(arguments_ref.is_slot());
219 // Here we rely on the convenient property that references to slot 231 // Here we rely on the convenient property that references to slot
220 // take up zero space in the frame (ie, it doesn't matter that the 232 // take up zero space in the frame (ie, it doesn't matter that the
221 // stored value is actually below the reference on the frame). 233 // stored value is actually below the reference on the frame).
222 arguments_ref.SetValue(NOT_CONST_INIT); 234 arguments_ref.SetValue(NOT_CONST_INIT);
223 } 235 }
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) { 540 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
529 ref->set_type(Reference::NAMED); 541 ref->set_type(Reference::NAMED);
530 } else { 542 } else {
531 Load(property->key()); 543 Load(property->key());
532 ref->set_type(Reference::KEYED); 544 ref->set_type(Reference::KEYED);
533 } 545 }
534 } else if (var != NULL) { 546 } else if (var != NULL) {
535 // The expression is a variable proxy that does not rewrite to a 547 // The expression is a variable proxy that does not rewrite to a
536 // property. Global variables are treated as named property references. 548 // property. Global variables are treated as named property references.
537 if (var->is_global()) { 549 if (var->is_global()) {
538 VirtualFrame::SpilledScope spilled_scope(this);
539 LoadGlobal(); 550 LoadGlobal();
540 ref->set_type(Reference::NAMED); 551 ref->set_type(Reference::NAMED);
541 } else { 552 } else {
542 ASSERT(var->slot() != NULL); 553 ASSERT(var->slot() != NULL);
543 ref->set_type(Reference::SLOT); 554 ref->set_type(Reference::SLOT);
544 } 555 }
545 } else { 556 } else {
546 // Anything else is a runtime error. 557 // Anything else is a runtime error.
547 Load(e); 558 Load(e);
548 frame_->CallRuntime(Runtime::kThrowReferenceError, 1); 559 frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
1490 node->set_break_stack_height(break_stack_height_); 1501 node->set_break_stack_height(break_stack_height_);
1491 node->break_target()->Initialize(this); 1502 node->break_target()->Initialize(this);
1492 VisitStatements(node->statements()); 1503 VisitStatements(node->statements());
1493 if (node->break_target()->is_linked()) { 1504 if (node->break_target()->is_linked()) {
1494 node->break_target()->Bind(); 1505 node->break_target()->Bind();
1495 } 1506 }
1496 } 1507 }
1497 1508
1498 1509
1499 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1510 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1500 VirtualFrame::SpilledScope spilled_scope(this); 1511 frame_->Push(pairs);
1501 frame_->EmitPush(Immediate(pairs)); 1512
1502 frame_->EmitPush(esi); 1513 // Duplicate the context register.
1503 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); 1514 Result context(esi, this);
1504 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 1515 frame_->Push(&context);
1516
1517 frame_->Push(Smi::FromInt(is_eval() ? 1 : 0));
1518 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
1505 // Return value is ignored. 1519 // Return value is ignored.
1506 } 1520 }
1507 1521
1508 1522
1509 void CodeGenerator::VisitDeclaration(Declaration* node) { 1523 void CodeGenerator::VisitDeclaration(Declaration* node) {
1510 Comment cmnt(masm_, "[ Declaration"); 1524 Comment cmnt(masm_, "[ Declaration");
1511 CodeForStatementPosition(node); 1525 CodeForStatementPosition(node);
1512 Variable* var = node->proxy()->var(); 1526 Variable* var = node->proxy()->var();
1513 ASSERT(var != NULL); // must have been resolved 1527 ASSERT(var != NULL); // must have been resolved
1514 Slot* slot = var->slot(); 1528 Slot* slot = var->slot();
1515 1529
1516 // If it was not possible to allocate the variable at compile time, 1530 // If it was not possible to allocate the variable at compile time,
1517 // we need to "declare" it at runtime to make sure it actually 1531 // we need to "declare" it at runtime to make sure it actually
1518 // exists in the local context. 1532 // exists in the local context.
1519 if (slot != NULL && slot->type() == Slot::LOOKUP) { 1533 if (slot != NULL && slot->type() == Slot::LOOKUP) {
1520 // Variables with a "LOOKUP" slot were introduced as non-locals 1534 // Variables with a "LOOKUP" slot were introduced as non-locals
1521 // during variable resolution and must have mode DYNAMIC. 1535 // during variable resolution and must have mode DYNAMIC.
1522 ASSERT(var->mode() == Variable::DYNAMIC); 1536 ASSERT(var->mode() == Variable::DYNAMIC);
1523 // For now, just do a runtime call. 1537 // For now, just do a runtime call. Duplicate the context register.
1524 VirtualFrame::SpilledScope spilled_scope(this); 1538 Result context(esi, this);
1525 frame_->EmitPush(esi); 1539 frame_->Push(&context);
1526 frame_->EmitPush(Immediate(var->name())); 1540 frame_->Push(var->name());
1527 // Declaration nodes are always introduced in one of two modes. 1541 // Declaration nodes are always introduced in one of two modes.
1528 ASSERT(node->mode() == Variable::VAR || node->mode() == Variable::CONST); 1542 ASSERT(node->mode() == Variable::VAR || node->mode() == Variable::CONST);
1529 PropertyAttributes attr = node->mode() == Variable::VAR ? NONE : READ_ONLY; 1543 PropertyAttributes attr = node->mode() == Variable::VAR ? NONE : READ_ONLY;
1530 frame_->EmitPush(Immediate(Smi::FromInt(attr))); 1544 frame_->Push(Smi::FromInt(attr));
1531 // Push initial value, if any. 1545 // Push initial value, if any.
1532 // Note: For variables we must not push an initial value (such as 1546 // Note: For variables we must not push an initial value (such as
1533 // 'undefined') because we may have a (legal) redeclaration and we 1547 // 'undefined') because we may have a (legal) redeclaration and we
1534 // must not destroy the current value. 1548 // must not destroy the current value.
1535 if (node->mode() == Variable::CONST) { 1549 if (node->mode() == Variable::CONST) {
1536 frame_->EmitPush(Immediate(Factory::the_hole_value())); 1550 frame_->Push(Factory::the_hole_value());
1537 } else if (node->fun() != NULL) { 1551 } else if (node->fun() != NULL) {
1538 LoadAndSpill(node->fun()); 1552 Load(node->fun());
1539 } else { 1553 } else {
1540 frame_->EmitPush(Immediate(0)); // no initial value! 1554 frame_->Push(Smi::FromInt(0)); // no initial value!
1541 } 1555 }
1542 frame_->CallRuntime(Runtime::kDeclareContextSlot, 4); 1556 Result ignored = frame_->CallRuntime(Runtime::kDeclareContextSlot, 4);
1543 // Ignore the return value (declarations are statements). 1557 // Ignore the return value (declarations are statements).
1544 return; 1558 return;
1545 } 1559 }
1546 1560
1547 ASSERT(!var->is_global()); 1561 ASSERT(!var->is_global());
1548 1562
1549 // If we have a function or a constant, we need to initialize the variable. 1563 // If we have a function or a constant, we need to initialize the variable.
1550 Expression* val = NULL; 1564 Expression* val = NULL;
1551 if (node->mode() == Variable::CONST) { 1565 if (node->mode() == Variable::CONST) {
1552 val = new Literal(Factory::the_hole_value()); 1566 val = new Literal(Factory::the_hole_value());
1553 } else { 1567 } else {
1554 val = node->fun(); // NULL if we don't have a function 1568 val = node->fun(); // NULL if we don't have a function
1555 } 1569 }
1556 1570
1557 if (val != NULL) { 1571 if (val != NULL) {
1558 VirtualFrame::SpilledScope spilled_scope(this);
1559 { 1572 {
1560 // Set initial value. 1573 // Set the initial value.
1561 Reference target(this, node->proxy()); 1574 Reference target(this, node->proxy());
1562 LoadAndSpill(val); 1575 Load(val);
1563 target.SetValue(NOT_CONST_INIT); 1576 target.SetValue(NOT_CONST_INIT);
1564 // The reference is removed from the stack (preserving TOS) when 1577 // The reference is removed from the stack (preserving TOS) when
1565 // it goes out of scope. 1578 // it goes out of scope.
1566 } 1579 }
1567 // Get rid of the assigned value (declarations are statements). 1580 // Get rid of the assigned value (declarations are statements).
1568 frame_->Drop(); 1581 frame_->Drop();
1569 } 1582 }
1570 } 1583 }
1571 1584
1572 1585
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after
3387 target.SetValue(CONST_INIT); 3400 target.SetValue(CONST_INIT);
3388 } else { 3401 } else {
3389 target.SetValue(NOT_CONST_INIT); 3402 target.SetValue(NOT_CONST_INIT);
3390 } 3403 }
3391 } 3404 }
3392 } 3405 }
3393 } 3406 }
3394 3407
3395 3408
3396 void CodeGenerator::VisitThrow(Throw* node) { 3409 void CodeGenerator::VisitThrow(Throw* node) {
3397 VirtualFrame::SpilledScope spilled_scope(this);
3398 Comment cmnt(masm_, "[ Throw"); 3410 Comment cmnt(masm_, "[ Throw");
3399 CodeForStatementPosition(node); 3411 CodeForStatementPosition(node);
3400 3412
3401 LoadAndSpill(node->exception()); 3413 Load(node->exception());
3402 frame_->CallRuntime(Runtime::kThrow, 1); 3414 Result result = frame_->CallRuntime(Runtime::kThrow, 1);
3403 frame_->EmitPush(eax); 3415 frame_->Push(&result);
3404 } 3416 }
3405 3417
3406 3418
3407 void CodeGenerator::VisitProperty(Property* node) { 3419 void CodeGenerator::VisitProperty(Property* node) {
3408 Comment cmnt(masm_, "[ Property"); 3420 Comment cmnt(masm_, "[ Property");
3409 Reference property(this, node); 3421 Reference property(this, node);
3410 property.GetValue(typeof_state()); 3422 property.GetValue(typeof_state());
3411 } 3423 }
3412 3424
3413 3425
(...skipping 3129 matching lines...) Expand 10 before | Expand all | Expand 10 after
6543 6555
6544 // Slow-case: Go through the JavaScript implementation. 6556 // Slow-case: Go through the JavaScript implementation.
6545 __ bind(&slow); 6557 __ bind(&slow);
6546 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6558 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6547 } 6559 }
6548 6560
6549 6561
6550 #undef __ 6562 #undef __
6551 6563
6552 } } // namespace v8::internal 6564 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698