OLD | NEW |
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 5409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5420 // Block the constant pool for one more instruction after leaving this | 5420 // Block the constant pool for one more instruction after leaving this |
5421 // constant pool block scope to include the branch instruction ending the | 5421 // constant pool block scope to include the branch instruction ending the |
5422 // deferred code. | 5422 // deferred code. |
5423 __ BlockConstPoolFor(1); | 5423 __ BlockConstPoolFor(1); |
5424 } | 5424 } |
5425 } | 5425 } |
5426 | 5426 |
5427 | 5427 |
5428 class DeferredReferenceGetKeyedValue: public DeferredCode { | 5428 class DeferredReferenceGetKeyedValue: public DeferredCode { |
5429 public: | 5429 public: |
5430 DeferredReferenceGetKeyedValue() { | 5430 DeferredReferenceGetKeyedValue(Register key, Register receiver) |
| 5431 : key_(key), receiver_(receiver) { |
5431 set_comment("[ DeferredReferenceGetKeyedValue"); | 5432 set_comment("[ DeferredReferenceGetKeyedValue"); |
5432 } | 5433 } |
5433 | 5434 |
5434 virtual void Generate(); | 5435 virtual void Generate(); |
| 5436 |
| 5437 private: |
| 5438 Register key_; |
| 5439 Register receiver_; |
5435 }; | 5440 }; |
5436 | 5441 |
5437 | 5442 |
5438 void DeferredReferenceGetKeyedValue::Generate() { | 5443 void DeferredReferenceGetKeyedValue::Generate() { |
| 5444 ASSERT((key_.is(r0) && receiver_.is(r1)) || |
| 5445 (key_.is(r1) && receiver_.is(r0))); |
| 5446 |
5439 Register scratch1 = VirtualFrame::scratch0(); | 5447 Register scratch1 = VirtualFrame::scratch0(); |
5440 Register scratch2 = VirtualFrame::scratch1(); | 5448 Register scratch2 = VirtualFrame::scratch1(); |
5441 __ DecrementCounter(&Counters::keyed_load_inline, 1, scratch1, scratch2); | 5449 __ DecrementCounter(&Counters::keyed_load_inline, 1, scratch1, scratch2); |
5442 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1, scratch1, scratch2); | 5450 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1, scratch1, scratch2); |
5443 | 5451 |
| 5452 // Ensure key in r0 and receiver in r1 to match keyed load ic calling |
| 5453 // convention. |
| 5454 if (key_.is(r1)) { |
| 5455 __ Swap(r0, r1, ip); |
| 5456 } |
| 5457 |
5444 // The rest of the instructions in the deferred code must be together. | 5458 // The rest of the instructions in the deferred code must be together. |
5445 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 5459 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
5446 // Call keyed load IC. It has the arguments key and receiver in r0 and r1. | 5460 // Call keyed load IC. It has the arguments key and receiver in r0 and r1. |
5447 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 5461 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
5448 __ Call(ic, RelocInfo::CODE_TARGET); | 5462 __ Call(ic, RelocInfo::CODE_TARGET); |
5449 // The call must be followed by a nop instruction to indicate that the | 5463 // The call must be followed by a nop instruction to indicate that the |
5450 // keyed load has been inlined. | 5464 // keyed load has been inlined. |
5451 __ nop(PROPERTY_ACCESS_INLINED); | 5465 __ nop(PROPERTY_ACCESS_INLINED); |
5452 | 5466 |
5453 // Block the constant pool for one more instruction after leaving this | 5467 // Block the constant pool for one more instruction after leaving this |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5569 frame_->CallKeyedLoadIC(); | 5583 frame_->CallKeyedLoadIC(); |
5570 } else { | 5584 } else { |
5571 // Inline the keyed load. | 5585 // Inline the keyed load. |
5572 Comment cmnt(masm_, "[ Inlined load from keyed property"); | 5586 Comment cmnt(masm_, "[ Inlined load from keyed property"); |
5573 | 5587 |
5574 // Counter will be decremented in the deferred code. Placed here to avoid | 5588 // Counter will be decremented in the deferred code. Placed here to avoid |
5575 // having it in the instruction stream below where patching will occur. | 5589 // having it in the instruction stream below where patching will occur. |
5576 __ IncrementCounter(&Counters::keyed_load_inline, 1, | 5590 __ IncrementCounter(&Counters::keyed_load_inline, 1, |
5577 frame_->scratch0(), frame_->scratch1()); | 5591 frame_->scratch0(), frame_->scratch1()); |
5578 | 5592 |
5579 // Load the key and receiver from the stack to r0 and r1. | 5593 // Load the key and receiver from the stack. |
5580 frame_->PopToR1R0(); | 5594 Register key = frame_->PopToRegister(); |
5581 Register key = r0; | 5595 Register receiver = frame_->PopToRegister(key); |
5582 Register receiver = r1; | |
5583 VirtualFrame::SpilledScope spilled(frame_); | 5596 VirtualFrame::SpilledScope spilled(frame_); |
5584 | 5597 |
5585 // The deferred code expects key and receiver in r0 and r1. | 5598 // The deferred code expects key and receiver in registers. |
5586 DeferredReferenceGetKeyedValue* deferred = | 5599 DeferredReferenceGetKeyedValue* deferred = |
5587 new DeferredReferenceGetKeyedValue(); | 5600 new DeferredReferenceGetKeyedValue(key, receiver); |
5588 | 5601 |
5589 // Check that the receiver is a heap object. | 5602 // Check that the receiver is a heap object. |
5590 __ tst(receiver, Operand(kSmiTagMask)); | 5603 __ tst(receiver, Operand(kSmiTagMask)); |
5591 deferred->Branch(eq); | 5604 deferred->Branch(eq); |
5592 | 5605 |
5593 // The following instructions are the part of the inlined load keyed | 5606 // The following instructions are the part of the inlined load keyed |
5594 // property code which can be patched. Therefore the exact number of | 5607 // property code which can be patched. Therefore the exact number of |
5595 // instructions generated need to be fixed, so the constant pool is blocked | 5608 // instructions generated need to be fixed, so the constant pool is blocked |
5596 // while generating this code. | 5609 // while generating this code. |
5597 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 5610 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
(...skipping 4359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9957 | 9970 |
9958 // Just jump to runtime to add the two strings. | 9971 // Just jump to runtime to add the two strings. |
9959 __ bind(&string_add_runtime); | 9972 __ bind(&string_add_runtime); |
9960 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 9973 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
9961 } | 9974 } |
9962 | 9975 |
9963 | 9976 |
9964 #undef __ | 9977 #undef __ |
9965 | 9978 |
9966 } } // namespace v8::internal | 9979 } } // namespace v8::internal |
OLD | NEW |