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

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

Issue 2119007: ARM: Don't require the receiver on the stack for load IC... (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 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 // and y the receiver. 1363 // and y the receiver.
1364 VirtualFrame::SpilledScope spilled_scope(frame_); 1364 VirtualFrame::SpilledScope spilled_scope(frame_);
1365 1365
1366 ASSERT(ArgumentsMode() == LAZY_ARGUMENTS_ALLOCATION); 1366 ASSERT(ArgumentsMode() == LAZY_ARGUMENTS_ALLOCATION);
1367 ASSERT(arguments->IsArguments()); 1367 ASSERT(arguments->IsArguments());
1368 1368
1369 // Load applicand.apply onto the stack. This will usually 1369 // Load applicand.apply onto the stack. This will usually
1370 // give us a megamorphic load site. Not super, but it works. 1370 // give us a megamorphic load site. Not super, but it works.
1371 LoadAndSpill(applicand); 1371 LoadAndSpill(applicand);
1372 Handle<String> name = Factory::LookupAsciiSymbol("apply"); 1372 Handle<String> name = Factory::LookupAsciiSymbol("apply");
1373 frame_->Dup();
1373 frame_->CallLoadIC(name, RelocInfo::CODE_TARGET); 1374 frame_->CallLoadIC(name, RelocInfo::CODE_TARGET);
1374 frame_->EmitPush(r0); 1375 frame_->EmitPush(r0);
1375 1376
1376 // Load the receiver and the existing arguments object onto the 1377 // Load the receiver and the existing arguments object onto the
1377 // expression stack. Avoid allocating the arguments object here. 1378 // expression stack. Avoid allocating the arguments object here.
1378 LoadAndSpill(receiver); 1379 LoadAndSpill(receiver);
1379 LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); 1380 LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
1380 1381
1381 // Emit the source position information after having loaded the 1382 // Emit the source position information after having loaded the
1382 // receiver and the arguments. 1383 // receiver and the arguments.
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after
3002 __ bind(&fast); 3003 __ bind(&fast);
3003 } 3004 }
3004 3005
3005 // Load the global object. 3006 // Load the global object.
3006 LoadGlobal(); 3007 LoadGlobal();
3007 // Setup the name register and call load IC. 3008 // Setup the name register and call load IC.
3008 frame_->CallLoadIC(slot->var()->name(), 3009 frame_->CallLoadIC(slot->var()->name(),
3009 typeof_state == INSIDE_TYPEOF 3010 typeof_state == INSIDE_TYPEOF
3010 ? RelocInfo::CODE_TARGET 3011 ? RelocInfo::CODE_TARGET
3011 : RelocInfo::CODE_TARGET_CONTEXT); 3012 : RelocInfo::CODE_TARGET_CONTEXT);
3012 // Drop the global object. The result is in r0.
3013 frame_->Drop();
3014 } 3013 }
3015 3014
3016 3015
3017 void CodeGenerator::EmitDynamicLoadFromSlotFastCase(Slot* slot, 3016 void CodeGenerator::EmitDynamicLoadFromSlotFastCase(Slot* slot,
3018 TypeofState typeof_state, 3017 TypeofState typeof_state,
3019 JumpTarget* slow, 3018 JumpTarget* slow,
3020 JumpTarget* done) { 3019 JumpTarget* done) {
3021 // Generate fast-case code for variables that might be shadowed by 3020 // Generate fast-case code for variables that might be shadowed by
3022 // eval-introduced variables. Eval is used a lot without 3021 // eval-introduced variables. Eval is used a lot without
3023 // introducing variables. In those cases, we do not want to 3022 // introducing variables. In those cases, we do not want to
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
3417 // For a compound assignment the right-hand side is a binary operation 3416 // For a compound assignment the right-hand side is a binary operation
3418 // between the current property value and the actual right-hand side. 3417 // between the current property value and the actual right-hand side.
3419 if (is_trivial_receiver) { 3418 if (is_trivial_receiver) {
3420 Load(prop->obj()); 3419 Load(prop->obj());
3421 } else if (var != NULL) { 3420 } else if (var != NULL) {
3422 LoadGlobal(); 3421 LoadGlobal();
3423 } else { 3422 } else {
3424 frame_->Dup(); 3423 frame_->Dup();
3425 } 3424 }
3426 EmitNamedLoad(name, var != NULL); 3425 EmitNamedLoad(name, var != NULL);
3427 frame_->Drop(); // Receiver is left on the stack.
3428 frame_->EmitPush(r0); 3426 frame_->EmitPush(r0);
3429 3427
3430 // Perform the binary operation. 3428 // Perform the binary operation.
3431 Literal* literal = node->value()->AsLiteral(); 3429 Literal* literal = node->value()->AsLiteral();
3432 bool overwrite_value = 3430 bool overwrite_value =
3433 (node->value()->AsBinaryOperation() != NULL && 3431 (node->value()->AsBinaryOperation() != NULL &&
3434 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 3432 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
3435 if (literal != NULL && literal->handle()->IsSmi()) { 3433 if (literal != NULL && literal->handle()->IsSmi()) {
3436 SmiOperation(node->binary_op(), 3434 SmiOperation(node->binary_op(),
3437 literal->handle(), 3435 literal->handle(),
(...skipping 1985 matching lines...) Expand 10 before | Expand all | Expand 10 after
5423 default: 5421 default:
5424 UNREACHABLE(); 5422 UNREACHABLE();
5425 } 5423 }
5426 ASSERT((has_cc() && frame_->height() == original_height) || 5424 ASSERT((has_cc() && frame_->height() == original_height) ||
5427 (!has_cc() && frame_->height() == original_height + 1)); 5425 (!has_cc() && frame_->height() == original_height + 1));
5428 } 5426 }
5429 5427
5430 5428
5431 class DeferredReferenceGetNamedValue: public DeferredCode { 5429 class DeferredReferenceGetNamedValue: public DeferredCode {
5432 public: 5430 public:
5433 explicit DeferredReferenceGetNamedValue(Handle<String> name) : name_(name) { 5431 explicit DeferredReferenceGetNamedValue(Register receiver,
5432 Handle<String> name)
5433 : receiver_(receiver), name_(name) {
5434 set_comment("[ DeferredReferenceGetNamedValue"); 5434 set_comment("[ DeferredReferenceGetNamedValue");
5435 } 5435 }
5436 5436
5437 virtual void Generate(); 5437 virtual void Generate();
5438 5438
5439 private: 5439 private:
5440 Register receiver_;
5440 Handle<String> name_; 5441 Handle<String> name_;
5441 }; 5442 };
5442 5443
5443 5444
5444 void DeferredReferenceGetNamedValue::Generate() { 5445 void DeferredReferenceGetNamedValue::Generate() {
5446 ASSERT(receiver_.is(r0) || receiver_.is(r1));
5447
5445 Register scratch1 = VirtualFrame::scratch0(); 5448 Register scratch1 = VirtualFrame::scratch0();
5446 Register scratch2 = VirtualFrame::scratch1(); 5449 Register scratch2 = VirtualFrame::scratch1();
5447 __ DecrementCounter(&Counters::named_load_inline, 1, scratch1, scratch2); 5450 __ DecrementCounter(&Counters::named_load_inline, 1, scratch1, scratch2);
5448 __ IncrementCounter(&Counters::named_load_inline_miss, 1, scratch1, scratch2); 5451 __ IncrementCounter(&Counters::named_load_inline_miss, 1, scratch1, scratch2);
5449 5452
5450 // Setup the registers and call load IC. 5453 // Ensure receiver in r0 and name in r2 to match load ic calling convention.
5451 // On entry to this deferred code, r0 is assumed to already contain the 5454 __ Move(r0, receiver_);
5452 // receiver from the top of the stack.
5453 __ mov(r2, Operand(name_)); 5455 __ mov(r2, Operand(name_));
5454 5456
5455 // The rest of the instructions in the deferred code must be together. 5457 // The rest of the instructions in the deferred code must be together.
5456 { Assembler::BlockConstPoolScope block_const_pool(masm_); 5458 { Assembler::BlockConstPoolScope block_const_pool(masm_);
5457 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 5459 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
5458 __ Call(ic, RelocInfo::CODE_TARGET); 5460 __ Call(ic, RelocInfo::CODE_TARGET);
5459 // The call must be followed by a nop(1) instruction to indicate that the 5461 // The call must be followed by a nop(1) instruction to indicate that the
5460 // in-object has been inlined. 5462 // in-object has been inlined.
5461 __ nop(PROPERTY_ACCESS_INLINED); 5463 __ nop(PROPERTY_ACCESS_INLINED);
5462 5464
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
5581 // having it in the instruction stream below where patching will occur. 5583 // having it in the instruction stream below where patching will occur.
5582 __ IncrementCounter(&Counters::named_load_inline, 1, 5584 __ IncrementCounter(&Counters::named_load_inline, 1,
5583 frame_->scratch0(), frame_->scratch1()); 5585 frame_->scratch0(), frame_->scratch1());
5584 5586
5585 // The following instructions are the inlined load of an in-object property. 5587 // The following instructions are the inlined load of an in-object property.
5586 // Parts of this code is patched, so the exact instructions generated needs 5588 // Parts of this code is patched, so the exact instructions generated needs
5587 // to be fixed. Therefore the instruction pool is blocked when generating 5589 // to be fixed. Therefore the instruction pool is blocked when generating
5588 // this code 5590 // this code
5589 5591
5590 // Load the receiver from the stack. 5592 // Load the receiver from the stack.
5591 frame_->SpillAllButCopyTOSToR0(); 5593 Register receiver = frame_->PopToRegister();
5594 VirtualFrame::SpilledScope spilled(frame_);
5592 5595
5593 DeferredReferenceGetNamedValue* deferred = 5596 DeferredReferenceGetNamedValue* deferred =
5594 new DeferredReferenceGetNamedValue(name); 5597 new DeferredReferenceGetNamedValue(receiver, name);
5595 5598
5596 #ifdef DEBUG 5599 #ifdef DEBUG
5597 int kInlinedNamedLoadInstructions = 7; 5600 int kInlinedNamedLoadInstructions = 7;
5598 Label check_inlined_codesize; 5601 Label check_inlined_codesize;
5599 masm_->bind(&check_inlined_codesize); 5602 masm_->bind(&check_inlined_codesize);
5600 #endif 5603 #endif
5601 5604
5602 { Assembler::BlockConstPoolScope block_const_pool(masm_); 5605 { Assembler::BlockConstPoolScope block_const_pool(masm_);
5603 // Check that the receiver is a heap object. 5606 // Check that the receiver is a heap object.
5604 __ tst(r0, Operand(kSmiTagMask)); 5607 __ tst(receiver, Operand(kSmiTagMask));
5605 deferred->Branch(eq); 5608 deferred->Branch(eq);
5606 5609
5607 // Check the map. The null map used below is patched by the inline cache 5610 // Check the map. The null map used below is patched by the inline cache
5608 // code. 5611 // code.
5609 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 5612 __ ldr(r2, FieldMemOperand(receiver, HeapObject::kMapOffset));
5610 __ mov(r3, Operand(Factory::null_value())); 5613 __ mov(r3, Operand(Factory::null_value()));
5611 __ cmp(r2, r3); 5614 __ cmp(r2, r3);
5612 deferred->Branch(ne); 5615 deferred->Branch(ne);
5613 5616
5614 // Initially use an invalid index. The index will be patched by the 5617 // Initially use an invalid index. The index will be patched by the
5615 // inline cache code. 5618 // inline cache code.
5616 __ ldr(r0, MemOperand(r0, 0)); 5619 __ ldr(r0, MemOperand(receiver, 0));
5617 5620
5618 // Make sure that the expected number of instructions are generated. 5621 // Make sure that the expected number of instructions are generated.
5619 ASSERT_EQ(kInlinedNamedLoadInstructions, 5622 ASSERT_EQ(kInlinedNamedLoadInstructions,
5620 masm_->InstructionsGeneratedSince(&check_inlined_codesize)); 5623 masm_->InstructionsGeneratedSince(&check_inlined_codesize));
5621 } 5624 }
5622 5625
5623 deferred->BindExit(); 5626 deferred->BindExit();
5624 } 5627 }
5625 } 5628 }
5626 5629
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
5855 if (!persist_after_get_) { 5858 if (!persist_after_get_) {
5856 cgen_->UnloadReference(this); 5859 cgen_->UnloadReference(this);
5857 } 5860 }
5858 break; 5861 break;
5859 } 5862 }
5860 5863
5861 case NAMED: { 5864 case NAMED: {
5862 Variable* var = expression_->AsVariableProxy()->AsVariable(); 5865 Variable* var = expression_->AsVariableProxy()->AsVariable();
5863 bool is_global = var != NULL; 5866 bool is_global = var != NULL;
5864 ASSERT(!is_global || var->is_global()); 5867 ASSERT(!is_global || var->is_global());
5868 if (persist_after_get_) {
5869 cgen_->frame()->Dup();
5870 }
5865 cgen_->EmitNamedLoad(GetName(), is_global); 5871 cgen_->EmitNamedLoad(GetName(), is_global);
5866 cgen_->frame()->EmitPush(r0); 5872 cgen_->frame()->EmitPush(r0);
5867 if (!persist_after_get_) { 5873 if (!persist_after_get_) set_unloaded();
5868 cgen_->UnloadReference(this);
5869 }
5870 break; 5874 break;
5871 } 5875 }
5872 5876
5873 case KEYED: { 5877 case KEYED: {
5878 ASSERT(property != NULL);
5874 if (persist_after_get_) { 5879 if (persist_after_get_) {
5875 cgen_->frame()->Dup2(); 5880 cgen_->frame()->Dup2();
5876 } 5881 }
5877 ASSERT(property != NULL);
5878 cgen_->EmitKeyedLoad(); 5882 cgen_->EmitKeyedLoad();
5879 cgen_->frame()->EmitPush(r0); 5883 cgen_->frame()->EmitPush(r0);
5880 if (!persist_after_get_) set_unloaded(); 5884 if (!persist_after_get_) set_unloaded();
5881 break; 5885 break;
5882 } 5886 }
5883 5887
5884 default: 5888 default:
5885 UNREACHABLE(); 5889 UNREACHABLE();
5886 } 5890 }
5887 } 5891 }
(...skipping 4147 matching lines...) Expand 10 before | Expand all | Expand 10 after
10035 __ bind(&string_add_runtime); 10039 __ bind(&string_add_runtime);
10036 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 10040 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
10037 } 10041 }
10038 10042
10039 10043
10040 #undef __ 10044 #undef __
10041 10045
10042 } } // namespace v8::internal 10046 } } // namespace v8::internal
10043 10047
10044 #endif // V8_TARGET_ARCH_ARM 10048 #endif // V8_TARGET_ARCH_ARM
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