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

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

Issue 2024002: Pass key and receiver in registers for keyed load IC on ARM... (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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm/full-codegen-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 3455 matching lines...) Expand 10 before | Expand all | Expand 10 after
3466 3466
3467 // Stack layout: 3467 // Stack layout:
3468 // [tos] : key 3468 // [tos] : key
3469 // [tos+1] : receiver 3469 // [tos+1] : receiver
3470 // [tos+2] : receiver if at the end of an initialization block 3470 // [tos+2] : receiver if at the end of an initialization block
3471 3471
3472 // Evaluate the right-hand side. 3472 // Evaluate the right-hand side.
3473 if (node->is_compound()) { 3473 if (node->is_compound()) {
3474 // For a compound assignment the right-hand side is a binary operation 3474 // For a compound assignment the right-hand side is a binary operation
3475 // between the current property value and the actual right-hand side. 3475 // between the current property value and the actual right-hand side.
3476 // Load of the current value leaves receiver and key on the stack. 3476 // Duplicate receiver and key for loading the current property value.
3477 frame_->Dup2();
3477 EmitKeyedLoad(); 3478 EmitKeyedLoad();
3478 frame_->EmitPush(r0); 3479 frame_->EmitPush(r0);
3479 3480
3480 // Perform the binary operation. 3481 // Perform the binary operation.
3481 Literal* literal = node->value()->AsLiteral(); 3482 Literal* literal = node->value()->AsLiteral();
3482 bool overwrite_value = 3483 bool overwrite_value =
3483 (node->value()->AsBinaryOperation() != NULL && 3484 (node->value()->AsBinaryOperation() != NULL &&
3484 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 3485 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
3485 if (literal != NULL && literal->handle()->IsSmi()) { 3486 if (literal != NULL && literal->handle()->IsSmi()) {
3486 SmiOperation(node->binary_op(), 3487 SmiOperation(node->binary_op(),
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
3760 __ ldr(cp, frame_->Context()); 3761 __ ldr(cp, frame_->Context());
3761 frame_->EmitPush(r0); 3762 frame_->EmitPush(r0);
3762 } 3763 }
3763 3764
3764 } else { 3765 } else {
3765 // ------------------------------------------- 3766 // -------------------------------------------
3766 // JavaScript example: 'array[index](1, 2, 3)' 3767 // JavaScript example: 'array[index](1, 2, 3)'
3767 // ------------------------------------------- 3768 // -------------------------------------------
3768 3769
3769 LoadAndSpill(property->obj()); 3770 LoadAndSpill(property->obj());
3771 if (!property->is_synthetic()) {
3772 // Duplicate receiver for later use.
3773 __ ldr(r0, MemOperand(sp, 0));
3774 frame_->EmitPush(r0);
3775 }
3770 LoadAndSpill(property->key()); 3776 LoadAndSpill(property->key());
3771 EmitKeyedLoad(); 3777 EmitKeyedLoad();
3772 frame_->Drop(); // key
3773 // Put the function below the receiver. 3778 // Put the function below the receiver.
3774 if (property->is_synthetic()) { 3779 if (property->is_synthetic()) {
3775 // Use the global receiver. 3780 // Use the global receiver.
3776 frame_->Drop(); 3781 frame_->EmitPush(r0); // Function.
3777 frame_->EmitPush(r0);
3778 LoadGlobalReceiver(r0); 3782 LoadGlobalReceiver(r0);
3779 } else { 3783 } else {
3780 frame_->EmitPop(r1); // receiver 3784 // Switch receiver and function.
3781 frame_->EmitPush(r0); // function 3785 frame_->EmitPop(r1); // Receiver.
3782 frame_->EmitPush(r1); // receiver 3786 frame_->EmitPush(r0); // Function.
3787 frame_->EmitPush(r1); // Receiver.
3783 } 3788 }
3784 3789
3785 // Call the function. 3790 // Call the function.
3786 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); 3791 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
3787 frame_->EmitPush(r0); 3792 frame_->EmitPush(r0);
3788 } 3793 }
3789 3794
3790 } else { 3795 } else {
3791 // ---------------------------------- 3796 // ----------------------------------
3792 // JavaScript example: 'foo(1, 2, 3)' // foo is not global 3797 // JavaScript example: 'foo(1, 2, 3)' // foo is not global
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after
5381 5386
5382 5387
5383 void DeferredReferenceGetKeyedValue::Generate() { 5388 void DeferredReferenceGetKeyedValue::Generate() {
5384 Register scratch1 = VirtualFrame::scratch0(); 5389 Register scratch1 = VirtualFrame::scratch0();
5385 Register scratch2 = VirtualFrame::scratch1(); 5390 Register scratch2 = VirtualFrame::scratch1();
5386 __ DecrementCounter(&Counters::keyed_load_inline, 1, scratch1, scratch2); 5391 __ DecrementCounter(&Counters::keyed_load_inline, 1, scratch1, scratch2);
5387 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1, scratch1, scratch2); 5392 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1, scratch1, scratch2);
5388 5393
5389 // The rest of the instructions in the deferred code must be together. 5394 // The rest of the instructions in the deferred code must be together.
5390 { Assembler::BlockConstPoolScope block_const_pool(masm_); 5395 { Assembler::BlockConstPoolScope block_const_pool(masm_);
5391 // Call keyed load IC. It has all arguments on the stack and the key in r0. 5396 // Call keyed load IC. It has the arguments key and receiver in r0 and r1.
5392 __ ldr(r0, MemOperand(sp, 0));
5393 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 5397 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
5394 __ Call(ic, RelocInfo::CODE_TARGET); 5398 __ Call(ic, RelocInfo::CODE_TARGET);
5395 // The call must be followed by a nop instruction to indicate that the 5399 // The call must be followed by a nop instruction to indicate that the
5396 // keyed load has been inlined. 5400 // keyed load has been inlined.
5397 __ nop(PROPERTY_ACCESS_INLINED); 5401 __ nop(PROPERTY_ACCESS_INLINED);
5398 5402
5399 // Block the constant pool for one more instruction after leaving this 5403 // Block the constant pool for one more instruction after leaving this
5400 // constant pool block scope to include the branch instruction ending the 5404 // constant pool block scope to include the branch instruction ending the
5401 // deferred code. 5405 // deferred code.
5402 __ BlockConstPoolFor(1); 5406 __ BlockConstPoolFor(1);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
5515 frame_->CallKeyedLoadIC(); 5519 frame_->CallKeyedLoadIC();
5516 } else { 5520 } else {
5517 // Inline the keyed load. 5521 // Inline the keyed load.
5518 Comment cmnt(masm_, "[ Inlined load from keyed property"); 5522 Comment cmnt(masm_, "[ Inlined load from keyed property");
5519 5523
5520 // Counter will be decremented in the deferred code. Placed here to avoid 5524 // Counter will be decremented in the deferred code. Placed here to avoid
5521 // having it in the instruction stream below where patching will occur. 5525 // having it in the instruction stream below where patching will occur.
5522 __ IncrementCounter(&Counters::keyed_load_inline, 1, 5526 __ IncrementCounter(&Counters::keyed_load_inline, 1,
5523 frame_->scratch0(), frame_->scratch1()); 5527 frame_->scratch0(), frame_->scratch1());
5524 5528
5525 // Load the receiver and key from the stack. 5529 // Load the key and receiver from the stack to r0 and r1.
5526 frame_->SpillAllButCopyTOSToR1R0(); 5530 frame_->PopToR1R0();
5527 Register receiver = r0; 5531 Register receiver = r0;
5528 Register key = r1; 5532 Register key = r1;
5529 VirtualFrame::SpilledScope spilled(frame_); 5533 VirtualFrame::SpilledScope spilled(frame_);
5530 5534
5535 // The deferred code expects key and receiver in r0 and r1.
5531 DeferredReferenceGetKeyedValue* deferred = 5536 DeferredReferenceGetKeyedValue* deferred =
5532 new DeferredReferenceGetKeyedValue(); 5537 new DeferredReferenceGetKeyedValue();
5533 5538
5534 // Check that the receiver is a heap object. 5539 // Check that the receiver is a heap object.
5535 __ tst(receiver, Operand(kSmiTagMask)); 5540 __ tst(receiver, Operand(kSmiTagMask));
5536 deferred->Branch(eq); 5541 deferred->Branch(eq);
5537 5542
5538 // The following instructions are the part of the inlined load keyed 5543 // The following instructions are the part of the inlined load keyed
5539 // property code which can be patched. Therefore the exact number of 5544 // property code which can be patched. Therefore the exact number of
5540 // instructions generated need to be fixed, so the constant pool is blocked 5545 // instructions generated need to be fixed, so the constant pool is blocked
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
5714 if (property != NULL) { 5719 if (property != NULL) {
5715 cgen_->CodeForSourcePosition(property->position()); 5720 cgen_->CodeForSourcePosition(property->position());
5716 } 5721 }
5717 5722
5718 switch (type_) { 5723 switch (type_) {
5719 case SLOT: { 5724 case SLOT: {
5720 Comment cmnt(masm, "[ Load from Slot"); 5725 Comment cmnt(masm, "[ Load from Slot");
5721 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); 5726 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
5722 ASSERT(slot != NULL); 5727 ASSERT(slot != NULL);
5723 cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); 5728 cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
5729 if (!persist_after_get_) {
5730 cgen_->UnloadReference(this);
5731 }
5724 break; 5732 break;
5725 } 5733 }
5726 5734
5727 case NAMED: { 5735 case NAMED: {
5728 Variable* var = expression_->AsVariableProxy()->AsVariable(); 5736 Variable* var = expression_->AsVariableProxy()->AsVariable();
5729 bool is_global = var != NULL; 5737 bool is_global = var != NULL;
5730 ASSERT(!is_global || var->is_global()); 5738 ASSERT(!is_global || var->is_global());
5731 cgen_->EmitNamedLoad(GetName(), is_global); 5739 cgen_->EmitNamedLoad(GetName(), is_global);
5732 cgen_->frame()->EmitPush(r0); 5740 cgen_->frame()->EmitPush(r0);
5741 if (!persist_after_get_) {
5742 cgen_->UnloadReference(this);
5743 }
5733 break; 5744 break;
5734 } 5745 }
5735 5746
5736 case KEYED: { 5747 case KEYED: {
5748 if (persist_after_get_) {
5749 cgen_->frame()->Dup2();
5750 }
5737 ASSERT(property != NULL); 5751 ASSERT(property != NULL);
5738 cgen_->EmitKeyedLoad(); 5752 cgen_->EmitKeyedLoad();
5739 cgen_->frame()->EmitPush(r0); 5753 cgen_->frame()->EmitPush(r0);
5754 if (!persist_after_get_) set_unloaded();
5740 break; 5755 break;
5741 } 5756 }
5742 5757
5743 default: 5758 default:
5744 UNREACHABLE(); 5759 UNREACHABLE();
5745 } 5760 }
5746
5747 if (!persist_after_get_) {
5748 cgen_->UnloadReference(this);
5749 }
5750 } 5761 }
5751 5762
5752 5763
5753 void Reference::SetValue(InitState init_state) { 5764 void Reference::SetValue(InitState init_state) {
5754 ASSERT(!is_illegal()); 5765 ASSERT(!is_illegal());
5755 ASSERT(!cgen_->has_cc()); 5766 ASSERT(!cgen_->has_cc());
5756 MacroAssembler* masm = cgen_->masm(); 5767 MacroAssembler* masm = cgen_->masm();
5757 VirtualFrame* frame = cgen_->frame(); 5768 VirtualFrame* frame = cgen_->frame();
5758 Property* property = expression_->AsProperty(); 5769 Property* property = expression_->AsProperty();
5759 if (property != NULL) { 5770 if (property != NULL) {
(...skipping 4141 matching lines...) Expand 10 before | Expand all | Expand 10 after
9901 9912
9902 // Just jump to runtime to add the two strings. 9913 // Just jump to runtime to add the two strings.
9903 __ bind(&string_add_runtime); 9914 __ bind(&string_add_runtime);
9904 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 9915 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
9905 } 9916 }
9906 9917
9907 9918
9908 #undef __ 9919 #undef __
9909 9920
9910 } } // namespace v8::internal 9921 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698