Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/arm/codegen-arm.cc

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
1931 } 1931 }
1932 node->break_target()->Unuse(); 1932 node->break_target()->Unuse();
1933 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1933 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1934 } 1934 }
1935 1935
1936 1936
1937 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1937 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1938 frame_->EmitPush(cp); 1938 frame_->EmitPush(cp);
1939 frame_->EmitPush(Operand(pairs)); 1939 frame_->EmitPush(Operand(pairs));
1940 frame_->EmitPush(Operand(Smi::FromInt(is_eval() ? 1 : 0))); 1940 frame_->EmitPush(Operand(Smi::FromInt(is_eval() ? 1 : 0)));
1941 frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag())));
1941 1942
1942 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 1943 frame_->CallRuntime(Runtime::kDeclareGlobals, 4);
1943 // The result is discarded. 1944 // The result is discarded.
1944 } 1945 }
1945 1946
1946 1947
1947 void CodeGenerator::VisitDeclaration(Declaration* node) { 1948 void CodeGenerator::VisitDeclaration(Declaration* node) {
1948 #ifdef DEBUG 1949 #ifdef DEBUG
1949 int original_height = frame_->height(); 1950 int original_height = frame_->height();
1950 #endif 1951 #endif
1951 Comment cmnt(masm_, "[ Declaration"); 1952 Comment cmnt(masm_, "[ Declaration");
1952 Variable* var = node->proxy()->var(); 1953 Variable* var = node->proxy()->var();
(...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after
3280 // context slot declaration, but we cannot initialize it at the 3281 // context slot declaration, but we cannot initialize it at the
3281 // same time, because the const declaration may be at the end of 3282 // same time, because the const declaration may be at the end of
3282 // the eval code (sigh...) and the const variable may have been 3283 // the eval code (sigh...) and the const variable may have been
3283 // used before (where its value is 'undefined'). Thus, we can only 3284 // used before (where its value is 'undefined'). Thus, we can only
3284 // do the initialization when we actually encounter the expression 3285 // do the initialization when we actually encounter the expression
3285 // and when the expression operands are defined and valid, and 3286 // and when the expression operands are defined and valid, and
3286 // thus we need the split into 2 operations: declaration of the 3287 // thus we need the split into 2 operations: declaration of the
3287 // context slot followed by initialization. 3288 // context slot followed by initialization.
3288 frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); 3289 frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
3289 } else { 3290 } else {
3290 frame_->CallRuntime(Runtime::kStoreContextSlot, 3); 3291 frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag())));
3292 frame_->CallRuntime(Runtime::kStoreContextSlot, 4);
3291 } 3293 }
3292 // Storing a variable must keep the (new) value on the expression 3294 // Storing a variable must keep the (new) value on the expression
3293 // stack. This is necessary for compiling assignment expressions. 3295 // stack. This is necessary for compiling assignment expressions.
3294 frame_->EmitPush(r0); 3296 frame_->EmitPush(r0);
3295 3297
3296 } else { 3298 } else {
3297 ASSERT(!slot->var()->is_dynamic()); 3299 ASSERT(!slot->var()->is_dynamic());
3298 Register scratch = VirtualFrame::scratch0(); 3300 Register scratch = VirtualFrame::scratch0();
3299 Register scratch2 = VirtualFrame::scratch1(); 3301 Register scratch2 = VirtualFrame::scratch1();
3300 3302
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
3631 frame_->Drop(); 3633 frame_->Drop();
3632 } 3634 }
3633 break; 3635 break;
3634 } 3636 }
3635 // else fall through 3637 // else fall through
3636 case ObjectLiteral::Property::PROTOTYPE: { 3638 case ObjectLiteral::Property::PROTOTYPE: {
3637 frame_->Dup(); 3639 frame_->Dup();
3638 Load(key); 3640 Load(key);
3639 Load(value); 3641 Load(value);
3640 if (property->emit_store()) { 3642 if (property->emit_store()) {
3641 frame_->CallRuntime(Runtime::kSetProperty, 3); 3643 frame_->EmitPush(Operand(Smi::FromInt(NONE))); // PropertyAttributes
3644 frame_->CallRuntime(Runtime::kSetProperty, 4);
3642 } else { 3645 } else {
3643 frame_->Drop(3); 3646 frame_->Drop(3);
3644 } 3647 }
3645 break; 3648 break;
3646 } 3649 }
3647 case ObjectLiteral::Property::SETTER: { 3650 case ObjectLiteral::Property::SETTER: {
3648 frame_->Dup(); 3651 frame_->Dup();
3649 Load(key); 3652 Load(key);
3650 frame_->EmitPush(Operand(Smi::FromInt(1))); 3653 frame_->EmitPush(Operand(Smi::FromInt(1)));
3651 Load(value); 3654 Load(value);
(...skipping 1515 matching lines...) Expand 10 before | Expand all | Expand 10 after
5167 __ ldr(scratch2_, 5170 __ ldr(scratch2_,
5168 FieldMemOperand(scratch2_, GlobalObject::kGlobalContextOffset)); 5171 FieldMemOperand(scratch2_, GlobalObject::kGlobalContextOffset));
5169 __ ldr(scratch2_, 5172 __ ldr(scratch2_,
5170 ContextOperand( 5173 ContextOperand(
5171 scratch2_, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); 5174 scratch2_, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
5172 __ cmp(scratch1_, scratch2_); 5175 __ cmp(scratch1_, scratch2_);
5173 __ b(ne, &false_result); 5176 __ b(ne, &false_result);
5174 5177
5175 // Set the bit in the map to indicate that it has been checked safe for 5178 // Set the bit in the map to indicate that it has been checked safe for
5176 // default valueOf and set true result. 5179 // default valueOf and set true result.
5177 __ ldr(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset)); 5180 __ ldrb(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset));
5178 __ orr(scratch1_, 5181 __ orr(scratch1_,
5179 scratch1_, 5182 scratch1_,
5180 Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); 5183 Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
5181 __ str(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset)); 5184 __ strb(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset));
5182 __ mov(map_result_, Operand(1)); 5185 __ mov(map_result_, Operand(1));
5183 __ jmp(exit_label()); 5186 __ jmp(exit_label());
5184 __ bind(&false_result); 5187 __ bind(&false_result);
5185 // Set false result. 5188 // Set false result.
5186 __ mov(map_result_, Operand(0, RelocInfo::NONE)); 5189 __ mov(map_result_, Operand(0, RelocInfo::NONE));
5187 } 5190 }
5188 5191
5189 private: 5192 private:
5190 Register object_; 5193 Register object_;
5191 Register map_result_; 5194 Register map_result_;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
5653 Load(args->at(n_args + 1)); // function 5656 Load(args->at(n_args + 1)); // function
5654 frame_->CallJSFunction(n_args); 5657 frame_->CallJSFunction(n_args);
5655 frame_->EmitPush(r0); 5658 frame_->EmitPush(r0);
5656 } 5659 }
5657 5660
5658 5661
5659 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { 5662 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
5660 ASSERT_EQ(args->length(), 1); 5663 ASSERT_EQ(args->length(), 1);
5661 Load(args->at(0)); 5664 Load(args->at(0));
5662 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { 5665 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
5663 TranscendentalCacheStub stub(TranscendentalCache::SIN); 5666 TranscendentalCacheStub stub(TranscendentalCache::SIN,
5667 TranscendentalCacheStub::TAGGED);
5664 frame_->SpillAllButCopyTOSToR0(); 5668 frame_->SpillAllButCopyTOSToR0();
5665 frame_->CallStub(&stub, 1); 5669 frame_->CallStub(&stub, 1);
5666 } else { 5670 } else {
5667 frame_->CallRuntime(Runtime::kMath_sin, 1); 5671 frame_->CallRuntime(Runtime::kMath_sin, 1);
5668 } 5672 }
5669 frame_->EmitPush(r0); 5673 frame_->EmitPush(r0);
5670 } 5674 }
5671 5675
5672 5676
5673 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { 5677 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
5674 ASSERT_EQ(args->length(), 1); 5678 ASSERT_EQ(args->length(), 1);
5675 Load(args->at(0)); 5679 Load(args->at(0));
5676 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { 5680 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
5677 TranscendentalCacheStub stub(TranscendentalCache::COS); 5681 TranscendentalCacheStub stub(TranscendentalCache::COS,
5682 TranscendentalCacheStub::TAGGED);
5678 frame_->SpillAllButCopyTOSToR0(); 5683 frame_->SpillAllButCopyTOSToR0();
5679 frame_->CallStub(&stub, 1); 5684 frame_->CallStub(&stub, 1);
5680 } else { 5685 } else {
5681 frame_->CallRuntime(Runtime::kMath_cos, 1); 5686 frame_->CallRuntime(Runtime::kMath_cos, 1);
5682 } 5687 }
5683 frame_->EmitPush(r0); 5688 frame_->EmitPush(r0);
5684 } 5689 }
5685 5690
5686 5691
5687 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) { 5692 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
5688 ASSERT_EQ(args->length(), 1); 5693 ASSERT_EQ(args->length(), 1);
5689 Load(args->at(0)); 5694 Load(args->at(0));
5690 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { 5695 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
5691 TranscendentalCacheStub stub(TranscendentalCache::LOG); 5696 TranscendentalCacheStub stub(TranscendentalCache::LOG,
5697 TranscendentalCacheStub::TAGGED);
5692 frame_->SpillAllButCopyTOSToR0(); 5698 frame_->SpillAllButCopyTOSToR0();
5693 frame_->CallStub(&stub, 1); 5699 frame_->CallStub(&stub, 1);
5694 } else { 5700 } else {
5695 frame_->CallRuntime(Runtime::kMath_log, 1); 5701 frame_->CallRuntime(Runtime::kMath_log, 1);
5696 } 5702 }
5697 frame_->EmitPush(r0); 5703 frame_->EmitPush(r0);
5698 } 5704 }
5699 5705
5700 5706
5701 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 5707 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
5842 // LoadCondition may (and usually does) leave a test and branch to 5848 // LoadCondition may (and usually does) leave a test and branch to
5843 // be emitted by the caller. In that case, negate the condition. 5849 // be emitted by the caller. In that case, negate the condition.
5844 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); 5850 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_);
5845 5851
5846 } else if (op == Token::DELETE) { 5852 } else if (op == Token::DELETE) {
5847 Property* property = node->expression()->AsProperty(); 5853 Property* property = node->expression()->AsProperty();
5848 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); 5854 Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
5849 if (property != NULL) { 5855 if (property != NULL) {
5850 Load(property->obj()); 5856 Load(property->obj());
5851 Load(property->key()); 5857 Load(property->key());
5852 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2); 5858 frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag())));
5859 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 3);
5853 frame_->EmitPush(r0); 5860 frame_->EmitPush(r0);
5854 5861
5855 } else if (variable != NULL) { 5862 } else if (variable != NULL) {
5863 // Delete of an unqualified identifier is disallowed in strict mode
5864 // but "delete this" is.
5865 ASSERT(strict_mode_flag() == kNonStrictMode || variable->is_this());
5856 Slot* slot = variable->AsSlot(); 5866 Slot* slot = variable->AsSlot();
5857 if (variable->is_global()) { 5867 if (variable->is_global()) {
5858 LoadGlobal(); 5868 LoadGlobal();
5859 frame_->EmitPush(Operand(variable->name())); 5869 frame_->EmitPush(Operand(variable->name()));
5860 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 2); 5870 frame_->EmitPush(Operand(Smi::FromInt(kNonStrictMode)));
5871 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 3);
5861 frame_->EmitPush(r0); 5872 frame_->EmitPush(r0);
5862 5873
5863 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 5874 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
5864 // Delete from the context holding the named variable. 5875 // Delete from the context holding the named variable.
5865 frame_->EmitPush(cp); 5876 frame_->EmitPush(cp);
5866 frame_->EmitPush(Operand(variable->name())); 5877 frame_->EmitPush(Operand(variable->name()));
5867 frame_->CallRuntime(Runtime::kDeleteContextSlot, 2); 5878 frame_->CallRuntime(Runtime::kDeleteContextSlot, 2);
5868 frame_->EmitPush(r0); 5879 frame_->EmitPush(r0);
5869 5880
5870 } else { 5881 } else {
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
6671 // deferred code. 6682 // deferred code.
6672 __ BlockConstPoolFor(1); 6683 __ BlockConstPoolFor(1);
6673 } 6684 }
6674 } 6685 }
6675 6686
6676 6687
6677 class DeferredReferenceSetKeyedValue: public DeferredCode { 6688 class DeferredReferenceSetKeyedValue: public DeferredCode {
6678 public: 6689 public:
6679 DeferredReferenceSetKeyedValue(Register value, 6690 DeferredReferenceSetKeyedValue(Register value,
6680 Register key, 6691 Register key,
6681 Register receiver) 6692 Register receiver,
6682 : value_(value), key_(key), receiver_(receiver) { 6693 StrictModeFlag strict_mode)
6694 : value_(value),
6695 key_(key),
6696 receiver_(receiver),
6697 strict_mode_(strict_mode) {
6683 set_comment("[ DeferredReferenceSetKeyedValue"); 6698 set_comment("[ DeferredReferenceSetKeyedValue");
6684 } 6699 }
6685 6700
6686 virtual void Generate(); 6701 virtual void Generate();
6687 6702
6688 private: 6703 private:
6689 Register value_; 6704 Register value_;
6690 Register key_; 6705 Register key_;
6691 Register receiver_; 6706 Register receiver_;
6707 StrictModeFlag strict_mode_;
6692 }; 6708 };
6693 6709
6694 6710
6695 void DeferredReferenceSetKeyedValue::Generate() { 6711 void DeferredReferenceSetKeyedValue::Generate() {
6696 Register scratch1 = VirtualFrame::scratch0(); 6712 Register scratch1 = VirtualFrame::scratch0();
6697 Register scratch2 = VirtualFrame::scratch1(); 6713 Register scratch2 = VirtualFrame::scratch1();
6698 __ DecrementCounter(COUNTERS->keyed_store_inline(), 1, scratch1, scratch2); 6714 __ DecrementCounter(COUNTERS->keyed_store_inline(), 1, scratch1, scratch2);
6699 __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 6715 __ IncrementCounter(COUNTERS->keyed_store_inline_miss(),
6700 1, scratch1, scratch2); 6716 1, scratch1, scratch2);
6701 6717
6702 // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic 6718 // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic
6703 // calling convention. 6719 // calling convention.
6704 if (value_.is(r1)) { 6720 if (value_.is(r1)) {
6705 __ Swap(r0, r1, ip); 6721 __ Swap(r0, r1, ip);
6706 } 6722 }
6707 ASSERT(receiver_.is(r2)); 6723 ASSERT(receiver_.is(r2));
6708 6724
6709 // The rest of the instructions in the deferred code must be together. 6725 // The rest of the instructions in the deferred code must be together.
6710 { Assembler::BlockConstPoolScope block_const_pool(masm_); 6726 { Assembler::BlockConstPoolScope block_const_pool(masm_);
6711 // Call keyed store IC. It has the arguments value, key and receiver in r0, 6727 // Call keyed store IC. It has the arguments value, key and receiver in r0,
6712 // r1 and r2. 6728 // r1 and r2.
6713 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 6729 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
6714 Builtins::KeyedStoreIC_Initialize)); 6730 (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
6731 : Builtins::KeyedStoreIC_Initialize));
6715 __ Call(ic, RelocInfo::CODE_TARGET); 6732 __ Call(ic, RelocInfo::CODE_TARGET);
6716 // The call must be followed by a nop instruction to indicate that the 6733 // The call must be followed by a nop instruction to indicate that the
6717 // keyed store has been inlined. 6734 // keyed store has been inlined.
6718 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); 6735 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED);
6719 6736
6720 // Block the constant pool for one more instruction after leaving this 6737 // Block the constant pool for one more instruction after leaving this
6721 // constant pool block scope to include the branch instruction ending the 6738 // constant pool block scope to include the branch instruction ending the
6722 // deferred code. 6739 // deferred code.
6723 __ BlockConstPoolFor(1); 6740 __ BlockConstPoolFor(1);
6724 } 6741 }
6725 } 6742 }
6726 6743
6727 6744
6728 class DeferredReferenceSetNamedValue: public DeferredCode { 6745 class DeferredReferenceSetNamedValue: public DeferredCode {
6729 public: 6746 public:
6730 DeferredReferenceSetNamedValue(Register value, 6747 DeferredReferenceSetNamedValue(Register value,
6731 Register receiver, 6748 Register receiver,
6732 Handle<String> name) 6749 Handle<String> name,
6733 : value_(value), receiver_(receiver), name_(name) { 6750 StrictModeFlag strict_mode)
6751 : value_(value),
6752 receiver_(receiver),
6753 name_(name),
6754 strict_mode_(strict_mode) {
6734 set_comment("[ DeferredReferenceSetNamedValue"); 6755 set_comment("[ DeferredReferenceSetNamedValue");
6735 } 6756 }
6736 6757
6737 virtual void Generate(); 6758 virtual void Generate();
6738 6759
6739 private: 6760 private:
6740 Register value_; 6761 Register value_;
6741 Register receiver_; 6762 Register receiver_;
6742 Handle<String> name_; 6763 Handle<String> name_;
6764 StrictModeFlag strict_mode_;
6743 }; 6765 };
6744 6766
6745 6767
6746 // Takes value in r0, receiver in r1 and returns the result (the 6768 // Takes value in r0, receiver in r1 and returns the result (the
6747 // value) in r0. 6769 // value) in r0.
6748 void DeferredReferenceSetNamedValue::Generate() { 6770 void DeferredReferenceSetNamedValue::Generate() {
6749 // Record the entry frame and spill. 6771 // Record the entry frame and spill.
6750 VirtualFrame copied_frame(*frame_state()->frame()); 6772 VirtualFrame copied_frame(*frame_state()->frame());
6751 copied_frame.SpillAll(); 6773 copied_frame.SpillAll();
6752 6774
6753 // Ensure value in r0, receiver in r1 to match store ic calling 6775 // Ensure value in r0, receiver in r1 to match store ic calling
6754 // convention. 6776 // convention.
6755 ASSERT(value_.is(r0) && receiver_.is(r1)); 6777 ASSERT(value_.is(r0) && receiver_.is(r1));
6756 __ mov(r2, Operand(name_)); 6778 __ mov(r2, Operand(name_));
6757 6779
6758 // The rest of the instructions in the deferred code must be together. 6780 // The rest of the instructions in the deferred code must be together.
6759 { Assembler::BlockConstPoolScope block_const_pool(masm_); 6781 { Assembler::BlockConstPoolScope block_const_pool(masm_);
6760 // Call keyed store IC. It has the arguments value, key and receiver in r0, 6782 // Call keyed store IC. It has the arguments value, key and receiver in r0,
6761 // r1 and r2. 6783 // r1 and r2.
6762 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 6784 Handle<Code> ic(Isolate::Current()->builtins()->builtin(
6763 Builtins::StoreIC_Initialize)); 6785 (strict_mode_ == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
6786 : Builtins::StoreIC_Initialize));
6764 __ Call(ic, RelocInfo::CODE_TARGET); 6787 __ Call(ic, RelocInfo::CODE_TARGET);
6765 // The call must be followed by a nop instruction to indicate that the 6788 // The call must be followed by a nop instruction to indicate that the
6766 // named store has been inlined. 6789 // named store has been inlined.
6767 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); 6790 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED);
6768 6791
6769 // Go back to the frame we entered with. The instructions 6792 // Go back to the frame we entered with. The instructions
6770 // generated by this merge are skipped over by the inline store 6793 // generated by this merge are skipped over by the inline store
6771 // patching mechanism when looking for the branch instruction that 6794 // patching mechanism when looking for the branch instruction that
6772 // tells it where the code to patch is. 6795 // tells it where the code to patch is.
6773 copied_frame.MergeTo(frame_state()->frame()); 6796 copied_frame.MergeTo(frame_state()->frame());
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
6930 } 6953 }
6931 6954
6932 6955
6933 void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) { 6956 void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
6934 #ifdef DEBUG 6957 #ifdef DEBUG
6935 int expected_height = frame()->height() - (is_contextual ? 1 : 2); 6958 int expected_height = frame()->height() - (is_contextual ? 1 : 2);
6936 #endif 6959 #endif
6937 6960
6938 Result result; 6961 Result result;
6939 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) { 6962 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
6940 frame()->CallStoreIC(name, is_contextual); 6963 frame()->CallStoreIC(name, is_contextual, strict_mode_flag());
6941 } else { 6964 } else {
6942 // Inline the in-object property case. 6965 // Inline the in-object property case.
6943 JumpTarget slow, done; 6966 JumpTarget slow, done;
6944 6967
6945 // Get the value and receiver from the stack. 6968 // Get the value and receiver from the stack.
6946 frame()->PopToR0(); 6969 frame()->PopToR0();
6947 Register value = r0; 6970 Register value = r0;
6948 frame()->PopToR1(); 6971 frame()->PopToR1();
6949 Register receiver = r1; 6972 Register receiver = r1;
6950 6973
6951 DeferredReferenceSetNamedValue* deferred = 6974 DeferredReferenceSetNamedValue* deferred =
6952 new DeferredReferenceSetNamedValue(value, receiver, name); 6975 new DeferredReferenceSetNamedValue(
6976 value, receiver, name, strict_mode_flag());
6953 6977
6954 // Check that the receiver is a heap object. 6978 // Check that the receiver is a heap object.
6955 __ tst(receiver, Operand(kSmiTagMask)); 6979 __ tst(receiver, Operand(kSmiTagMask));
6956 deferred->Branch(eq); 6980 deferred->Branch(eq);
6957 6981
6958 // The following instructions are the part of the inlined 6982 // The following instructions are the part of the inlined
6959 // in-object property store code which can be patched. Therefore 6983 // in-object property store code which can be patched. Therefore
6960 // the exact number of instructions generated must be fixed, so 6984 // the exact number of instructions generated must be fixed, so
6961 // the constant pool is blocked while generating this code. 6985 // the constant pool is blocked while generating this code.
6962 { Assembler::BlockConstPoolScope block_const_pool(masm_); 6986 { Assembler::BlockConstPoolScope block_const_pool(masm_);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
7128 VirtualFrame::SpilledScope spilled(frame_); 7152 VirtualFrame::SpilledScope spilled(frame_);
7129 Register receiver = r2; 7153 Register receiver = r2;
7130 frame_->EmitPop(receiver); 7154 frame_->EmitPop(receiver);
7131 7155
7132 #ifdef DEBUG 7156 #ifdef DEBUG
7133 bool we_remembered_the_write_barrier = value_is_harmless; 7157 bool we_remembered_the_write_barrier = value_is_harmless;
7134 #endif 7158 #endif
7135 7159
7136 // The deferred code expects value, key and receiver in registers. 7160 // The deferred code expects value, key and receiver in registers.
7137 DeferredReferenceSetKeyedValue* deferred = 7161 DeferredReferenceSetKeyedValue* deferred =
7138 new DeferredReferenceSetKeyedValue(value, key, receiver); 7162 new DeferredReferenceSetKeyedValue(
7163 value, key, receiver, strict_mode_flag());
7139 7164
7140 // Check that the value is a smi. As this inlined code does not set the 7165 // Check that the value is a smi. As this inlined code does not set the
7141 // write barrier it is only possible to store smi values. 7166 // write barrier it is only possible to store smi values.
7142 if (!value_is_harmless) { 7167 if (!value_is_harmless) {
7143 // If the value is not likely to be a Smi then let's test the fixed array 7168 // If the value is not likely to be a Smi then let's test the fixed array
7144 // for new space instead. See below. 7169 // for new space instead. See below.
7145 if (wb_info == LIKELY_SMI) { 7170 if (wb_info == LIKELY_SMI) {
7146 __ tst(value, Operand(kSmiTagMask)); 7171 __ tst(value, Operand(kSmiTagMask));
7147 deferred->Branch(ne); 7172 deferred->Branch(ne);
7148 #ifdef DEBUG 7173 #ifdef DEBUG
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
7213 7238
7214 // Make sure that the expected number of instructions are generated. 7239 // Make sure that the expected number of instructions are generated.
7215 ASSERT_EQ(kInlinedKeyedStoreInstructionsAfterPatch, 7240 ASSERT_EQ(kInlinedKeyedStoreInstructionsAfterPatch,
7216 masm_->InstructionsGeneratedSince(&check_inlined_codesize)); 7241 masm_->InstructionsGeneratedSince(&check_inlined_codesize));
7217 } 7242 }
7218 7243
7219 ASSERT(we_remembered_the_write_barrier); 7244 ASSERT(we_remembered_the_write_barrier);
7220 7245
7221 deferred->BindExit(); 7246 deferred->BindExit();
7222 } else { 7247 } else {
7223 frame()->CallKeyedStoreIC(); 7248 frame()->CallKeyedStoreIC(strict_mode_flag());
7224 } 7249 }
7225 } 7250 }
7226 7251
7227 7252
7228 #ifdef DEBUG 7253 #ifdef DEBUG
7229 bool CodeGenerator::HasValidEntryRegisters() { return true; } 7254 bool CodeGenerator::HasValidEntryRegisters() { return true; }
7230 #endif 7255 #endif
7231 7256
7232 7257
7233 #undef __ 7258 #undef __
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
7380 specialized_on_rhs_ ? "_ConstantRhs" : "", 7405 specialized_on_rhs_ ? "_ConstantRhs" : "",
7381 BinaryOpIC::GetName(runtime_operands_type_)); 7406 BinaryOpIC::GetName(runtime_operands_type_));
7382 return name_; 7407 return name_;
7383 } 7408 }
7384 7409
7385 #undef __ 7410 #undef __
7386 7411
7387 } } // namespace v8::internal 7412 } } // namespace v8::internal
7388 7413
7389 #endif // V8_TARGET_ARCH_ARM 7414 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698