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