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 5241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5252 // context slot declaration, but we cannot initialize it at the same | 5252 // context slot declaration, but we cannot initialize it at the same |
5253 // time, because the const declaration may be at the end of the eval | 5253 // time, because the const declaration may be at the end of the eval |
5254 // code (sigh...) and the const variable may have been used before | 5254 // code (sigh...) and the const variable may have been used before |
5255 // (where its value is 'undefined'). Thus, we can only do the | 5255 // (where its value is 'undefined'). Thus, we can only do the |
5256 // initialization when we actually encounter the expression and when | 5256 // initialization when we actually encounter the expression and when |
5257 // the expression operands are defined and valid, and thus we need the | 5257 // the expression operands are defined and valid, and thus we need the |
5258 // split into 2 operations: declaration of the context slot followed | 5258 // split into 2 operations: declaration of the context slot followed |
5259 // by initialization. | 5259 // by initialization. |
5260 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 5260 value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
5261 } else { | 5261 } else { |
5262 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3); | 5262 frame_->Push(Smi::FromInt(strict_mode_flag())); |
| 5263 value = frame_->CallRuntime(Runtime::kStoreContextSlot, 4); |
5263 } | 5264 } |
5264 // Storing a variable must keep the (new) value on the expression | 5265 // Storing a variable must keep the (new) value on the expression |
5265 // stack. This is necessary for compiling chained assignment | 5266 // stack. This is necessary for compiling chained assignment |
5266 // expressions. | 5267 // expressions. |
5267 frame_->Push(&value); | 5268 frame_->Push(&value); |
5268 | 5269 |
5269 } else { | 5270 } else { |
5270 ASSERT(!slot->var()->is_dynamic()); | 5271 ASSERT(!slot->var()->is_dynamic()); |
5271 | 5272 |
5272 JumpTarget exit; | 5273 JumpTarget exit; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5601 break; | 5602 break; |
5602 } | 5603 } |
5603 // Fall through | 5604 // Fall through |
5604 } | 5605 } |
5605 case ObjectLiteral::Property::PROTOTYPE: { | 5606 case ObjectLiteral::Property::PROTOTYPE: { |
5606 // Duplicate the object as an argument to the runtime call. | 5607 // Duplicate the object as an argument to the runtime call. |
5607 frame_->Dup(); | 5608 frame_->Dup(); |
5608 Load(property->key()); | 5609 Load(property->key()); |
5609 Load(property->value()); | 5610 Load(property->value()); |
5610 if (property->emit_store()) { | 5611 if (property->emit_store()) { |
| 5612 frame_->Push(Smi::FromInt(NONE)); // PropertyAttributes |
5611 // Ignore the result. | 5613 // Ignore the result. |
5612 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3); | 5614 Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 4); |
5613 } else { | 5615 } else { |
5614 frame_->Drop(3); | 5616 frame_->Drop(3); |
5615 } | 5617 } |
5616 break; | 5618 break; |
5617 } | 5619 } |
5618 case ObjectLiteral::Property::SETTER: { | 5620 case ObjectLiteral::Property::SETTER: { |
5619 // Duplicate the object as an argument to the runtime call. | 5621 // Duplicate the object as an argument to the runtime call. |
5620 frame_->Dup(); | 5622 frame_->Dup(); |
5621 Load(property->key()); | 5623 Load(property->key()); |
5622 frame_->Push(Smi::FromInt(1)); | 5624 frame_->Push(Smi::FromInt(1)); |
(...skipping 3828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9451 | 9453 |
9452 if (!dst_.is(eax)) __ mov(dst_, eax); | 9454 if (!dst_.is(eax)) __ mov(dst_, eax); |
9453 } | 9455 } |
9454 | 9456 |
9455 | 9457 |
9456 class DeferredReferenceSetKeyedValue: public DeferredCode { | 9458 class DeferredReferenceSetKeyedValue: public DeferredCode { |
9457 public: | 9459 public: |
9458 DeferredReferenceSetKeyedValue(Register value, | 9460 DeferredReferenceSetKeyedValue(Register value, |
9459 Register key, | 9461 Register key, |
9460 Register receiver, | 9462 Register receiver, |
9461 Register scratch) | 9463 Register scratch, |
| 9464 StrictModeFlag strict) |
9462 : value_(value), | 9465 : value_(value), |
9463 key_(key), | 9466 key_(key), |
9464 receiver_(receiver), | 9467 receiver_(receiver), |
9465 scratch_(scratch) { | 9468 scratch_(scratch), |
| 9469 strict_(strict) { |
9466 set_comment("[ DeferredReferenceSetKeyedValue"); | 9470 set_comment("[ DeferredReferenceSetKeyedValue"); |
9467 } | 9471 } |
9468 | 9472 |
9469 virtual void Generate(); | 9473 virtual void Generate(); |
9470 | 9474 |
9471 Label* patch_site() { return &patch_site_; } | 9475 Label* patch_site() { return &patch_site_; } |
9472 | 9476 |
9473 private: | 9477 private: |
9474 Register value_; | 9478 Register value_; |
9475 Register key_; | 9479 Register key_; |
9476 Register receiver_; | 9480 Register receiver_; |
9477 Register scratch_; | 9481 Register scratch_; |
9478 Label patch_site_; | 9482 Label patch_site_; |
| 9483 StrictModeFlag strict_; |
9479 }; | 9484 }; |
9480 | 9485 |
9481 | 9486 |
9482 void DeferredReferenceSetKeyedValue::Generate() { | 9487 void DeferredReferenceSetKeyedValue::Generate() { |
9483 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1); | 9488 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1); |
9484 // Move value_ to eax, key_ to ecx, and receiver_ to edx. | 9489 // Move value_ to eax, key_ to ecx, and receiver_ to edx. |
9485 Register old_value = value_; | 9490 Register old_value = value_; |
9486 | 9491 |
9487 // First, move value to eax. | 9492 // First, move value to eax. |
9488 if (!value_.is(eax)) { | 9493 if (!value_.is(eax)) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9527 } | 9532 } |
9528 } | 9533 } |
9529 } else { // Key is not in edx or ecx. | 9534 } else { // Key is not in edx or ecx. |
9530 if (!receiver_.is(edx)) { | 9535 if (!receiver_.is(edx)) { |
9531 __ mov(edx, receiver_); | 9536 __ mov(edx, receiver_); |
9532 } | 9537 } |
9533 __ mov(ecx, key_); | 9538 __ mov(ecx, key_); |
9534 } | 9539 } |
9535 | 9540 |
9536 // Call the IC stub. | 9541 // Call the IC stub. |
9537 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 9542 Handle<Code> ic(Builtins::builtin( |
| 9543 strict_ == kStrictMode ? Builtins::KeyedStoreIC_Initialize_Strict |
| 9544 : Builtins::KeyedStoreIC_Initialize)); |
9538 __ call(ic, RelocInfo::CODE_TARGET); | 9545 __ call(ic, RelocInfo::CODE_TARGET); |
9539 // The delta from the start of the map-compare instruction to the | 9546 // The delta from the start of the map-compare instruction to the |
9540 // test instruction. We use masm_-> directly here instead of the | 9547 // test instruction. We use masm_-> directly here instead of the |
9541 // __ macro because the macro sometimes uses macro expansion to turn | 9548 // __ macro because the macro sometimes uses macro expansion to turn |
9542 // into something that can't return a value. This is encountered | 9549 // into something that can't return a value. This is encountered |
9543 // when doing generated code coverage tests. | 9550 // when doing generated code coverage tests. |
9544 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); | 9551 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); |
9545 // Here we use masm_-> instead of the __ macro because this is the | 9552 // Here we use masm_-> instead of the __ macro because this is the |
9546 // instruction that gets patched and coverage code gets in the way. | 9553 // instruction that gets patched and coverage code gets in the way. |
9547 masm_->test(eax, Immediate(-delta_to_patch_site)); | 9554 masm_->test(eax, Immediate(-delta_to_patch_site)); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9889 | 9896 |
9890 // Make sure that value, key and receiver are in registers. | 9897 // Make sure that value, key and receiver are in registers. |
9891 result.ToRegister(); | 9898 result.ToRegister(); |
9892 key.ToRegister(); | 9899 key.ToRegister(); |
9893 receiver.ToRegister(); | 9900 receiver.ToRegister(); |
9894 | 9901 |
9895 DeferredReferenceSetKeyedValue* deferred = | 9902 DeferredReferenceSetKeyedValue* deferred = |
9896 new DeferredReferenceSetKeyedValue(result.reg(), | 9903 new DeferredReferenceSetKeyedValue(result.reg(), |
9897 key.reg(), | 9904 key.reg(), |
9898 receiver.reg(), | 9905 receiver.reg(), |
9899 tmp.reg()); | 9906 tmp.reg(), |
| 9907 strict_mode_flag()); |
9900 | 9908 |
9901 // Check that the receiver is not a smi. | 9909 // Check that the receiver is not a smi. |
9902 __ test(receiver.reg(), Immediate(kSmiTagMask)); | 9910 __ test(receiver.reg(), Immediate(kSmiTagMask)); |
9903 deferred->Branch(zero); | 9911 deferred->Branch(zero); |
9904 | 9912 |
9905 // Check that the key is a smi. | 9913 // Check that the key is a smi. |
9906 if (!key.is_smi()) { | 9914 if (!key.is_smi()) { |
9907 __ test(key.reg(), Immediate(kSmiTagMask)); | 9915 __ test(key.reg(), Immediate(kSmiTagMask)); |
9908 deferred->Branch(not_zero); | 9916 deferred->Branch(not_zero); |
9909 } else { | 9917 } else { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9944 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), | 9952 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), |
9945 Immediate(Factory::fixed_array_map())); | 9953 Immediate(Factory::fixed_array_map())); |
9946 deferred->Branch(not_equal); | 9954 deferred->Branch(not_equal); |
9947 | 9955 |
9948 // Store the value. | 9956 // Store the value. |
9949 __ mov(FixedArrayElementOperand(tmp.reg(), key.reg()), result.reg()); | 9957 __ mov(FixedArrayElementOperand(tmp.reg(), key.reg()), result.reg()); |
9950 __ IncrementCounter(&Counters::keyed_store_inline, 1); | 9958 __ IncrementCounter(&Counters::keyed_store_inline, 1); |
9951 | 9959 |
9952 deferred->BindExit(); | 9960 deferred->BindExit(); |
9953 } else { | 9961 } else { |
9954 result = frame()->CallKeyedStoreIC(); | 9962 result = frame()->CallKeyedStoreIC(strict_mode_flag()); |
9955 // Make sure that we do not have a test instruction after the | 9963 // Make sure that we do not have a test instruction after the |
9956 // call. A test instruction after the call is used to | 9964 // call. A test instruction after the call is used to |
9957 // indicate that we have generated an inline version of the | 9965 // indicate that we have generated an inline version of the |
9958 // keyed store. | 9966 // keyed store. |
9959 __ nop(); | 9967 __ nop(); |
9960 } | 9968 } |
9961 ASSERT(frame()->height() == original_height - 3); | 9969 ASSERT(frame()->height() == original_height - 3); |
9962 return result; | 9970 return result; |
9963 } | 9971 } |
9964 | 9972 |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10324 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); | 10332 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); |
10325 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); | 10333 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); |
10326 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); | 10334 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); |
10327 } | 10335 } |
10328 | 10336 |
10329 #undef __ | 10337 #undef __ |
10330 | 10338 |
10331 } } // namespace v8::internal | 10339 } } // namespace v8::internal |
10332 | 10340 |
10333 #endif // V8_TARGET_ARCH_IA32 | 10341 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |