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 5003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5014 // Load the function to call from the property through a reference. | 5014 // Load the function to call from the property through a reference. |
5015 | 5015 |
5016 // Pass receiver to called function. | 5016 // Pass receiver to called function. |
5017 if (property->is_synthetic()) { | 5017 if (property->is_synthetic()) { |
5018 Reference ref(this, property); | 5018 Reference ref(this, property); |
5019 ref.GetValue(); | 5019 ref.GetValue(); |
5020 // Use global object as receiver. | 5020 // Use global object as receiver. |
5021 LoadGlobalReceiver(); | 5021 LoadGlobalReceiver(); |
5022 } else { | 5022 } else { |
5023 Load(property->obj()); | 5023 Load(property->obj()); |
| 5024 frame_->Dup(); |
5024 Load(property->key()); | 5025 Load(property->key()); |
5025 Result function = EmitKeyedLoad(false); | 5026 Result function = EmitKeyedLoad(false); |
5026 frame_->Drop(); // Key. | |
5027 Result receiver = frame_->Pop(); | 5027 Result receiver = frame_->Pop(); |
5028 frame_->Push(&function); | 5028 frame_->Push(&function); |
5029 frame_->Push(&receiver); | 5029 frame_->Push(&receiver); |
5030 } | 5030 } |
5031 | 5031 |
5032 // Call the function. | 5032 // Call the function. |
5033 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); | 5033 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); |
5034 } | 5034 } |
5035 | 5035 |
5036 } else { | 5036 } else { |
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6467 private: | 6467 private: |
6468 Label patch_site_; | 6468 Label patch_site_; |
6469 Register dst_; | 6469 Register dst_; |
6470 Register receiver_; | 6470 Register receiver_; |
6471 Register key_; | 6471 Register key_; |
6472 bool is_global_; | 6472 bool is_global_; |
6473 }; | 6473 }; |
6474 | 6474 |
6475 | 6475 |
6476 void DeferredReferenceGetKeyedValue::Generate() { | 6476 void DeferredReferenceGetKeyedValue::Generate() { |
6477 __ push(receiver_); // First IC argument. | 6477 if (!receiver_.is(eax)) { |
6478 __ push(key_); // Second IC argument. | 6478 // Register eax is available for key. |
6479 | 6479 if (!key_.is(eax)) { |
| 6480 __ mov(eax, key_); |
| 6481 } |
| 6482 if (!receiver_.is(edx)) { |
| 6483 __ mov(edx, receiver_); |
| 6484 } |
| 6485 } else if (!key_.is(edx)) { |
| 6486 // Register edx is available for receiver. |
| 6487 if (!receiver_.is(edx)) { |
| 6488 __ mov(edx, receiver_); |
| 6489 } |
| 6490 if (!key_.is(eax)) { |
| 6491 __ mov(eax, key_); |
| 6492 } |
| 6493 } else { |
| 6494 __ xchg(edx, eax); |
| 6495 } |
6480 // Calculate the delta from the IC call instruction to the map check | 6496 // Calculate the delta from the IC call instruction to the map check |
6481 // cmp instruction in the inlined version. This delta is stored in | 6497 // cmp instruction in the inlined version. This delta is stored in |
6482 // a test(eax, delta) instruction after the call so that we can find | 6498 // a test(eax, delta) instruction after the call so that we can find |
6483 // it in the IC initialization code and patch the cmp instruction. | 6499 // it in the IC initialization code and patch the cmp instruction. |
6484 // This means that we cannot allow test instructions after calls to | 6500 // This means that we cannot allow test instructions after calls to |
6485 // KeyedLoadIC stubs in other places. | 6501 // KeyedLoadIC stubs in other places. |
6486 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 6502 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
6487 RelocInfo::Mode mode = is_global_ | 6503 RelocInfo::Mode mode = is_global_ |
6488 ? RelocInfo::CODE_TARGET_CONTEXT | 6504 ? RelocInfo::CODE_TARGET_CONTEXT |
6489 : RelocInfo::CODE_TARGET; | 6505 : RelocInfo::CODE_TARGET; |
6490 __ call(ic, mode); | 6506 __ call(ic, mode); |
6491 // The delta from the start of the map-compare instruction to the | 6507 // The delta from the start of the map-compare instruction to the |
6492 // test instruction. We use masm_-> directly here instead of the __ | 6508 // test instruction. We use masm_-> directly here instead of the __ |
6493 // macro because the macro sometimes uses macro expansion to turn | 6509 // macro because the macro sometimes uses macro expansion to turn |
6494 // into something that can't return a value. This is encountered | 6510 // into something that can't return a value. This is encountered |
6495 // when doing generated code coverage tests. | 6511 // when doing generated code coverage tests. |
6496 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); | 6512 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); |
6497 // Here we use masm_-> instead of the __ macro because this is the | 6513 // Here we use masm_-> instead of the __ macro because this is the |
6498 // instruction that gets patched and coverage code gets in the way. | 6514 // instruction that gets patched and coverage code gets in the way. |
6499 masm_->test(eax, Immediate(-delta_to_patch_site)); | 6515 masm_->test(eax, Immediate(-delta_to_patch_site)); |
6500 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); | 6516 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); |
6501 | 6517 |
6502 if (!dst_.is(eax)) __ mov(dst_, eax); | 6518 if (!dst_.is(eax)) __ mov(dst_, eax); |
6503 __ pop(key_); | |
6504 __ pop(receiver_); | |
6505 } | 6519 } |
6506 | 6520 |
6507 | 6521 |
6508 class DeferredReferenceSetKeyedValue: public DeferredCode { | 6522 class DeferredReferenceSetKeyedValue: public DeferredCode { |
6509 public: | 6523 public: |
6510 DeferredReferenceSetKeyedValue(Register value, | 6524 DeferredReferenceSetKeyedValue(Register value, |
6511 Register key, | 6525 Register key, |
6512 Register receiver) | 6526 Register receiver) |
6513 : value_(value), key_(key), receiver_(receiver) { | 6527 : value_(value), key_(key), receiver_(receiver) { |
6514 set_comment("[ DeferredReferenceSetKeyedValue"); | 6528 set_comment("[ DeferredReferenceSetKeyedValue"); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6632 index.reg(), | 6646 index.reg(), |
6633 times_4, | 6647 times_4, |
6634 FixedArray::kHeaderSize - kHeapObjectTag)); | 6648 FixedArray::kHeaderSize - kHeapObjectTag)); |
6635 elements.Unuse(); | 6649 elements.Unuse(); |
6636 index.Unuse(); | 6650 index.Unuse(); |
6637 __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value())); | 6651 __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value())); |
6638 deferred->Branch(equal); | 6652 deferred->Branch(equal); |
6639 __ IncrementCounter(&Counters::keyed_load_inline, 1); | 6653 __ IncrementCounter(&Counters::keyed_load_inline, 1); |
6640 | 6654 |
6641 deferred->BindExit(); | 6655 deferred->BindExit(); |
6642 // Restore the receiver and key to the frame and push the | |
6643 // result on top of it. | |
6644 frame_->Push(&receiver); | |
6645 frame_->Push(&key); | |
6646 return value; | 6656 return value; |
6647 } else { | 6657 } else { |
6648 Comment cmnt(masm_, "[ Load from keyed Property"); | 6658 Comment cmnt(masm_, "[ Load from keyed Property"); |
6649 RelocInfo::Mode mode = is_global | 6659 RelocInfo::Mode mode = is_global |
6650 ? RelocInfo::CODE_TARGET_CONTEXT | 6660 ? RelocInfo::CODE_TARGET_CONTEXT |
6651 : RelocInfo::CODE_TARGET; | 6661 : RelocInfo::CODE_TARGET; |
6652 Result answer = frame_->CallKeyedLoadIC(mode); | 6662 Result answer = frame_->CallKeyedLoadIC(mode); |
6653 // Make sure that we do not have a test instruction after the | 6663 // Make sure that we do not have a test instruction after the |
6654 // call. A test instruction after the call is used to | 6664 // call. A test instruction after the call is used to |
6655 // indicate that we have generated an inline version of the | 6665 // indicate that we have generated an inline version of the |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6774 deferred->BindExit(); | 6784 deferred->BindExit(); |
6775 cgen_->frame()->Push(&value); | 6785 cgen_->frame()->Push(&value); |
6776 } | 6786 } |
6777 if (!persist_after_get_) { | 6787 if (!persist_after_get_) { |
6778 set_unloaded(); | 6788 set_unloaded(); |
6779 } | 6789 } |
6780 break; | 6790 break; |
6781 } | 6791 } |
6782 | 6792 |
6783 case KEYED: { | 6793 case KEYED: { |
| 6794 if (persist_after_get_) { |
| 6795 cgen_->frame()->PushElementAt(1); |
| 6796 cgen_->frame()->PushElementAt(1); |
| 6797 } |
6784 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 6798 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
6785 bool is_global = var != NULL; | 6799 bool is_global = var != NULL; |
6786 ASSERT(!is_global || var->is_global()); | 6800 ASSERT(!is_global || var->is_global()); |
6787 Result value = cgen_->EmitKeyedLoad(is_global); | 6801 Result value = cgen_->EmitKeyedLoad(is_global); |
6788 cgen_->frame()->Push(&value); | 6802 cgen_->frame()->Push(&value); |
6789 if (!persist_after_get_) { | 6803 if (!persist_after_get_) { |
6790 cgen_->UnloadReference(this); | 6804 set_unloaded(); |
6791 } | 6805 } |
6792 break; | 6806 break; |
6793 } | 6807 } |
6794 | 6808 |
6795 default: | 6809 default: |
6796 UNREACHABLE(); | 6810 UNREACHABLE(); |
6797 } | 6811 } |
6798 } | 6812 } |
6799 | 6813 |
6800 | 6814 |
(...skipping 3820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10621 | 10635 |
10622 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 10636 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
10623 // tagged as a small integer. | 10637 // tagged as a small integer. |
10624 __ bind(&runtime); | 10638 __ bind(&runtime); |
10625 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 10639 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
10626 } | 10640 } |
10627 | 10641 |
10628 #undef __ | 10642 #undef __ |
10629 | 10643 |
10630 } } // namespace v8::internal | 10644 } } // namespace v8::internal |
OLD | NEW |