OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2740 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 2740 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
2741 // Call the runtime to declare the globals. The inevitable call | 2741 // Call the runtime to declare the globals. The inevitable call |
2742 // will sync frame elements to memory anyway, so we do it eagerly to | 2742 // will sync frame elements to memory anyway, so we do it eagerly to |
2743 // allow us to push the arguments directly into place. | 2743 // allow us to push the arguments directly into place. |
2744 frame_->SyncRange(0, frame_->element_count() - 1); | 2744 frame_->SyncRange(0, frame_->element_count() - 1); |
2745 | 2745 |
2746 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT); | 2746 __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT); |
2747 frame_->EmitPush(rsi); // The context is the first argument. | 2747 frame_->EmitPush(rsi); // The context is the first argument. |
2748 frame_->EmitPush(kScratchRegister); | 2748 frame_->EmitPush(kScratchRegister); |
2749 frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0)); | 2749 frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0)); |
2750 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3); | 2750 frame_->EmitPush(Smi::FromInt(strict_mode_flag())); |
| 2751 Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 4); |
2751 // Return value is ignored. | 2752 // Return value is ignored. |
2752 } | 2753 } |
2753 | 2754 |
2754 | 2755 |
2755 void CodeGenerator::VisitDeclaration(Declaration* node) { | 2756 void CodeGenerator::VisitDeclaration(Declaration* node) { |
2756 Comment cmnt(masm_, "[ Declaration"); | 2757 Comment cmnt(masm_, "[ Declaration"); |
2757 Variable* var = node->proxy()->var(); | 2758 Variable* var = node->proxy()->var(); |
2758 ASSERT(var != NULL); // must have been resolved | 2759 ASSERT(var != NULL); // must have been resolved |
2759 Slot* slot = var->AsSlot(); | 2760 Slot* slot = var->AsSlot(); |
2760 | 2761 |
(...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4598 // context slot declaration, but we cannot initialize it at the same | 4599 // context slot declaration, but we cannot initialize it at the same |
4599 // time, because the const declaration may be at the end of the eval | 4600 // time, because the const declaration may be at the end of the eval |
4600 // code (sigh...) and the const variable may have been used before | 4601 // code (sigh...) and the const variable may have been used before |
4601 // (where its value is 'undefined'). Thus, we can only do the | 4602 // (where its value is 'undefined'). Thus, we can only do the |
4602 // initialization when we actually encounter the expression and when | 4603 // initialization when we actually encounter the expression and when |
4603 // the expression operands are defined and valid, and thus we need the | 4604 // the expression operands are defined and valid, and thus we need the |
4604 // split into 2 operations: declaration of the context slot followed | 4605 // split into 2 operations: declaration of the context slot followed |
4605 // by initialization. | 4606 // by initialization. |
4606 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 4607 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
4607 } else { | 4608 } else { |
4608 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3); | 4609 frame_->Push(Smi::FromInt(strict_mode_flag())); |
| 4610 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 4); |
4609 } | 4611 } |
4610 // Storing a variable must keep the (new) value on the expression | 4612 // Storing a variable must keep the (new) value on the expression |
4611 // stack. This is necessary for compiling chained assignment | 4613 // stack. This is necessary for compiling chained assignment |
4612 // expressions. | 4614 // expressions. |
4613 frame_->Push(&value); | 4615 frame_->Push(&value); |
4614 } else { | 4616 } else { |
4615 ASSERT(!slot->var()->is_dynamic()); | 4617 ASSERT(!slot->var()->is_dynamic()); |
4616 | 4618 |
4617 JumpTarget exit; | 4619 JumpTarget exit; |
4618 if (init_state == CONST_INIT) { | 4620 if (init_state == CONST_INIT) { |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4907 break; | 4909 break; |
4908 } | 4910 } |
4909 // Fall through | 4911 // Fall through |
4910 } | 4912 } |
4911 case ObjectLiteral::Property::PROTOTYPE: { | 4913 case ObjectLiteral::Property::PROTOTYPE: { |
4912 // Duplicate the object as an argument to the runtime call. | 4914 // Duplicate the object as an argument to the runtime call. |
4913 frame_->Dup(); | 4915 frame_->Dup(); |
4914 Load(property->key()); | 4916 Load(property->key()); |
4915 Load(property->value()); | 4917 Load(property->value()); |
4916 if (property->emit_store()) { | 4918 if (property->emit_store()) { |
| 4919 frame_->Push(Smi::FromInt(NONE)); // PropertyAttributes |
4917 // Ignore the result. | 4920 // Ignore the result. |
4918 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3); | 4921 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 4); |
4919 } else { | 4922 } else { |
4920 frame_->Drop(3); | 4923 frame_->Drop(3); |
4921 } | 4924 } |
4922 break; | 4925 break; |
4923 } | 4926 } |
4924 case ObjectLiteral::Property::SETTER: { | 4927 case ObjectLiteral::Property::SETTER: { |
4925 // Duplicate the object as an argument to the runtime call. | 4928 // Duplicate the object as an argument to the runtime call. |
4926 frame_->Dup(); | 4929 frame_->Dup(); |
4927 Load(property->key()); | 4930 Load(property->key()); |
4928 frame_->Push(Smi::FromInt(1)); | 4931 frame_->Push(Smi::FromInt(1)); |
(...skipping 3139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8068 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); | 8071 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); |
8069 | 8072 |
8070 if (!dst_.is(rax)) __ movq(dst_, rax); | 8073 if (!dst_.is(rax)) __ movq(dst_, rax); |
8071 } | 8074 } |
8072 | 8075 |
8073 | 8076 |
8074 class DeferredReferenceSetKeyedValue: public DeferredCode { | 8077 class DeferredReferenceSetKeyedValue: public DeferredCode { |
8075 public: | 8078 public: |
8076 DeferredReferenceSetKeyedValue(Register value, | 8079 DeferredReferenceSetKeyedValue(Register value, |
8077 Register key, | 8080 Register key, |
8078 Register receiver) | 8081 Register receiver, |
8079 : value_(value), key_(key), receiver_(receiver) { | 8082 StrictModeFlag strict_mode) |
| 8083 : value_(value), |
| 8084 key_(key), |
| 8085 receiver_(receiver), |
| 8086 strict_mode_(strict_mode) { |
8080 set_comment("[ DeferredReferenceSetKeyedValue"); | 8087 set_comment("[ DeferredReferenceSetKeyedValue"); |
8081 } | 8088 } |
8082 | 8089 |
8083 virtual void Generate(); | 8090 virtual void Generate(); |
8084 | 8091 |
8085 Label* patch_site() { return &patch_site_; } | 8092 Label* patch_site() { return &patch_site_; } |
8086 | 8093 |
8087 private: | 8094 private: |
8088 Register value_; | 8095 Register value_; |
8089 Register key_; | 8096 Register key_; |
8090 Register receiver_; | 8097 Register receiver_; |
8091 Label patch_site_; | 8098 Label patch_site_; |
| 8099 StrictModeFlag strict_mode_; |
8092 }; | 8100 }; |
8093 | 8101 |
8094 | 8102 |
8095 void DeferredReferenceSetKeyedValue::Generate() { | 8103 void DeferredReferenceSetKeyedValue::Generate() { |
8096 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1); | 8104 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1); |
8097 // Move value, receiver, and key to registers rax, rdx, and rcx, as | 8105 // Move value, receiver, and key to registers rax, rdx, and rcx, as |
8098 // the IC stub expects. | 8106 // the IC stub expects. |
8099 // Move value to rax, using xchg if the receiver or key is in rax. | 8107 // Move value to rax, using xchg if the receiver or key is in rax. |
8100 if (!value_.is(rax)) { | 8108 if (!value_.is(rax)) { |
8101 if (!receiver_.is(rax) && !key_.is(rax)) { | 8109 if (!receiver_.is(rax) && !key_.is(rax)) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8133 __ movq(rcx, key_); | 8141 __ movq(rcx, key_); |
8134 } | 8142 } |
8135 } else if (key_.is(rcx)) { | 8143 } else if (key_.is(rcx)) { |
8136 __ movq(rdx, receiver_); | 8144 __ movq(rdx, receiver_); |
8137 } else { | 8145 } else { |
8138 __ movq(rcx, key_); | 8146 __ movq(rcx, key_); |
8139 __ movq(rdx, receiver_); | 8147 __ movq(rdx, receiver_); |
8140 } | 8148 } |
8141 | 8149 |
8142 // Call the IC stub. | 8150 // Call the IC stub. |
8143 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 8151 Handle<Code> ic(Builtins::builtin( |
| 8152 (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict |
| 8153 : Builtins::KeyedStoreIC_Initialize)); |
8144 __ Call(ic, RelocInfo::CODE_TARGET); | 8154 __ Call(ic, RelocInfo::CODE_TARGET); |
8145 // The delta from the start of the map-compare instructions (initial movq) | 8155 // The delta from the start of the map-compare instructions (initial movq) |
8146 // to the test instruction. We use masm_-> directly here instead of the | 8156 // to the test instruction. We use masm_-> directly here instead of the |
8147 // __ macro because the macro sometimes uses macro expansion to turn | 8157 // __ macro because the macro sometimes uses macro expansion to turn |
8148 // into something that can't return a value. This is encountered | 8158 // into something that can't return a value. This is encountered |
8149 // when doing generated code coverage tests. | 8159 // when doing generated code coverage tests. |
8150 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); | 8160 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); |
8151 // Here we use masm_-> instead of the __ macro because this is the | 8161 // Here we use masm_-> instead of the __ macro because this is the |
8152 // instruction that gets patched and coverage code gets in the way. | 8162 // instruction that gets patched and coverage code gets in the way. |
8153 masm_->testl(rax, Immediate(-delta_to_patch_site)); | 8163 masm_->testl(rax, Immediate(-delta_to_patch_site)); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8474 bool value_is_constant = result.is_constant(); | 8484 bool value_is_constant = result.is_constant(); |
8475 | 8485 |
8476 // Make sure that value, key and receiver are in registers. | 8486 // Make sure that value, key and receiver are in registers. |
8477 result.ToRegister(); | 8487 result.ToRegister(); |
8478 key.ToRegister(); | 8488 key.ToRegister(); |
8479 receiver.ToRegister(); | 8489 receiver.ToRegister(); |
8480 | 8490 |
8481 DeferredReferenceSetKeyedValue* deferred = | 8491 DeferredReferenceSetKeyedValue* deferred = |
8482 new DeferredReferenceSetKeyedValue(result.reg(), | 8492 new DeferredReferenceSetKeyedValue(result.reg(), |
8483 key.reg(), | 8493 key.reg(), |
8484 receiver.reg()); | 8494 receiver.reg(), |
| 8495 strict_mode_flag()); |
8485 | 8496 |
8486 // Check that the receiver is not a smi. | 8497 // Check that the receiver is not a smi. |
8487 __ JumpIfSmi(receiver.reg(), deferred->entry_label()); | 8498 __ JumpIfSmi(receiver.reg(), deferred->entry_label()); |
8488 | 8499 |
8489 // Check that the key is a smi. | 8500 // Check that the key is a smi. |
8490 if (!key.is_smi()) { | 8501 if (!key.is_smi()) { |
8491 __ JumpIfNotSmi(key.reg(), deferred->entry_label()); | 8502 __ JumpIfNotSmi(key.reg(), deferred->entry_label()); |
8492 } else if (FLAG_debug_code) { | 8503 } else if (FLAG_debug_code) { |
8493 __ AbortIfNotSmi(key.reg()); | 8504 __ AbortIfNotSmi(key.reg()); |
8494 } | 8505 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8536 masm()->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); | 8547 masm()->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); |
8537 __ movq(FieldOperand(tmp.reg(), | 8548 __ movq(FieldOperand(tmp.reg(), |
8538 index.reg, | 8549 index.reg, |
8539 index.scale, | 8550 index.scale, |
8540 FixedArray::kHeaderSize), | 8551 FixedArray::kHeaderSize), |
8541 result.reg()); | 8552 result.reg()); |
8542 __ IncrementCounter(&Counters::keyed_store_inline, 1); | 8553 __ IncrementCounter(&Counters::keyed_store_inline, 1); |
8543 | 8554 |
8544 deferred->BindExit(); | 8555 deferred->BindExit(); |
8545 } else { | 8556 } else { |
8546 result = frame()->CallKeyedStoreIC(); | 8557 result = frame()->CallKeyedStoreIC(strict_mode_flag()); |
8547 // Make sure that we do not have a test instruction after the | 8558 // Make sure that we do not have a test instruction after the |
8548 // call. A test instruction after the call is used to | 8559 // call. A test instruction after the call is used to |
8549 // indicate that we have generated an inline version of the | 8560 // indicate that we have generated an inline version of the |
8550 // keyed store. | 8561 // keyed store. |
8551 __ nop(); | 8562 __ nop(); |
8552 } | 8563 } |
8553 ASSERT(frame()->height() == original_height - 3); | 8564 ASSERT(frame()->height() == original_height - 3); |
8554 return result; | 8565 return result; |
8555 } | 8566 } |
8556 | 8567 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8815 } | 8826 } |
8816 | 8827 |
8817 #endif | 8828 #endif |
8818 | 8829 |
8819 | 8830 |
8820 #undef __ | 8831 #undef __ |
8821 | 8832 |
8822 } } // namespace v8::internal | 8833 } } // namespace v8::internal |
8823 | 8834 |
8824 #endif // V8_TARGET_ARCH_X64 | 8835 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |