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

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

Issue 2053003: Refactor the fast-case code for loading local/global variables and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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/arm/codegen-arm.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 4644)
+++ src/arm/codegen-arm.cc (working copy)
@@ -2791,61 +2791,14 @@
JumpTarget slow;
JumpTarget done;
- // Generate fast-case code for variables that might be shadowed by
- // eval-introduced variables. Eval is used a lot without
- // introducing variables. In those cases, we do not want to
- // perform a runtime call for all variables in the scope
- // containing the eval.
- if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
- LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow);
- frame_->SpillAll();
- done.Jump();
+ // Generate fast case for loading from slots that correspond to
+ // local/global variables or arguments unless they are shadowed by
+ // eval-introduced bindings.
+ EmitDynamicLoadFromSlotFastCase(slot,
+ typeof_state,
+ &slow,
+ &done);
- } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
- frame_->SpillAll();
- Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
- Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
- if (potential_slot != NULL) {
- // Generate fast case for locals that rewrite to slots.
- __ ldr(r0,
- ContextSlotOperandCheckExtensions(potential_slot,
- r1,
- r2,
- &slow));
- if (potential_slot->var()->mode() == Variable::CONST) {
- __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
- __ cmp(r0, ip);
- __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
- }
- done.Jump();
- } else if (rewrite != NULL) {
- // Generate fast case for argument loads.
- Property* property = rewrite->AsProperty();
- if (property != NULL) {
- VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
- Literal* key_literal = property->key()->AsLiteral();
- if (obj_proxy != NULL &&
- key_literal != NULL &&
- obj_proxy->IsArguments() &&
- key_literal->handle()->IsSmi()) {
- // Load arguments object if there are no eval-introduced
- // variables. Then load the argument from the arguments
- // object using keyed load.
- __ ldr(r0,
- ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
- r1,
- r2,
- &slow));
- frame_->EmitPush(r0);
- __ mov(r1, Operand(key_literal->handle()));
- frame_->EmitPush(r1);
- EmitKeyedLoad();
- done.Jump();
- }
- }
- }
- }
-
slow.Bind();
VirtualFrame::SpilledScope spilled_scope(frame_);
frame_->EmitPush(cp);
@@ -3059,6 +3012,67 @@
}
+void CodeGenerator::EmitDynamicLoadFromSlotFastCase(Slot* slot,
+ TypeofState typeof_state,
+ JumpTarget* slow,
+ JumpTarget* done) {
+ // Generate fast-case code for variables that might be shadowed by
+ // eval-introduced variables. Eval is used a lot without
+ // introducing variables. In those cases, we do not want to
+ // perform a runtime call for all variables in the scope
+ // containing the eval.
+ if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
+ LoadFromGlobalSlotCheckExtensions(slot, typeof_state, slow);
+ frame_->SpillAll();
+ done->Jump();
+
+ } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
+ frame_->SpillAll();
+ Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
+ Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
+ if (potential_slot != NULL) {
+ // Generate fast case for locals that rewrite to slots.
+ __ ldr(r0,
+ ContextSlotOperandCheckExtensions(potential_slot,
+ r1,
+ r2,
+ slow));
+ if (potential_slot->var()->mode() == Variable::CONST) {
+ __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+ __ cmp(r0, ip);
+ __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
+ }
+ done->Jump();
+ } else if (rewrite != NULL) {
+ // Generate fast case for argument loads.
+ Property* property = rewrite->AsProperty();
+ if (property != NULL) {
+ VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
+ Literal* key_literal = property->key()->AsLiteral();
+ if (obj_proxy != NULL &&
+ key_literal != NULL &&
+ obj_proxy->IsArguments() &&
+ key_literal->handle()->IsSmi()) {
+ // Load arguments object if there are no eval-introduced
+ // variables. Then load the argument from the arguments
+ // object using keyed load.
+ __ ldr(r0,
+ ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
+ r1,
+ r2,
+ slow));
+ frame_->EmitPush(r0);
+ __ mov(r1, Operand(key_literal->handle()));
+ frame_->EmitPush(r1);
+ EmitKeyedLoad();
+ done->Jump();
+ }
+ }
+ }
+ }
+}
+
+
void CodeGenerator::VisitSlot(Slot* node) {
#ifdef DEBUG
int original_height = frame_->height();
@@ -3756,68 +3770,16 @@
// JumpTargets do not yet support merging frames so the frame must be
// spilled when jumping to these targets.
- JumpTarget slow;
- JumpTarget done;
+ JumpTarget slow, done;
- // Generate fast-case code for variables that might be shadowed by
- // eval-introduced variables. Eval is used a lot without
- // introducing variables. In those cases, we do not want to
- // perform a runtime call for all variables in the scope
- // containing the eval.
- if (var->mode() == Variable::DYNAMIC_GLOBAL) {
- LoadFromGlobalSlotCheckExtensions(var->slot(), NOT_INSIDE_TYPEOF, &slow);
- frame_->EmitPush(r0);
- LoadGlobalReceiver(r1);
- done.Jump();
+ // Generate fast case for loading functions from slots that
+ // correspond to local/global variables or arguments unless they
+ // are shadowed by eval-introduced bindings.
+ EmitDynamicLoadFromSlotFastCase(var->slot(),
+ NOT_INSIDE_TYPEOF,
+ &slow,
+ &done);
- } else if (var->mode() == Variable::DYNAMIC_LOCAL) {
- Slot* potential_slot = var->local_if_not_shadowed()->slot();
- Expression* rewrite = var->local_if_not_shadowed()->rewrite();
- if (potential_slot != NULL) {
- // Generate fast case for locals that rewrite to slots.
- __ ldr(r0,
- ContextSlotOperandCheckExtensions(potential_slot,
- r1,
- r2,
- &slow));
- if (potential_slot->var()->mode() == Variable::CONST) {
- __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
- __ cmp(r0, ip);
- __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
- }
- frame_->EmitPush(r0);
- LoadGlobalReceiver(r1);
- done.Jump();
- } else if (rewrite != NULL) {
- // Generate fast case for calls of an argument function.
- Property* property = rewrite->AsProperty();
- if (property != NULL) {
- VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
- Literal* key_literal = property->key()->AsLiteral();
- if (obj_proxy != NULL &&
- key_literal != NULL &&
- obj_proxy->IsArguments() &&
- key_literal->handle()->IsSmi()) {
- // Load arguments object if there are no eval-introduced
- // variables. Then load the argument from the arguments
- // object using keyed load.
- __ ldr(r0,
- ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
- r1,
- r2,
- &slow));
- frame_->EmitPush(r0);
- __ mov(r1, Operand(key_literal->handle()));
- frame_->EmitPush(r1);
- EmitKeyedLoad();
- frame_->EmitPush(r0);
- LoadGlobalReceiver(r1);
- done.Jump();
- }
- }
- }
- }
-
slow.Bind();
// Load the function
frame_->EmitPush(cp);
@@ -3830,7 +3792,18 @@
frame_->EmitPush(r0); // function
frame_->EmitPush(r1); // receiver
- done.Bind();
+ // If fast case code has been generated, emit code to push the
+ // function and receiver and have the slow path jump around this
+ // code.
+ if (done.is_linked()) {
+ JumpTarget call;
+ call.Jump();
+ done.Bind();
+ frame_->EmitPush(r0); // function
+ LoadGlobalReceiver(r1); // receiver
+ call.Bind();
+ }
+
// Call the function. At this point, everything is spilled but the
// function and receiver are in r0 and r1.
CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698