| 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 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 Register reg = frame_->GetTOSRegister(); | 574 Register reg = frame_->GetTOSRegister(); |
| 575 __ ldr(reg, ContextOperand(cp, Context::GLOBAL_INDEX)); | 575 __ ldr(reg, ContextOperand(cp, Context::GLOBAL_INDEX)); |
| 576 __ ldr(reg, | 576 __ ldr(reg, |
| 577 FieldMemOperand(reg, GlobalObject::kGlobalReceiverOffset)); | 577 FieldMemOperand(reg, GlobalObject::kGlobalReceiverOffset)); |
| 578 frame_->EmitPush(reg); | 578 frame_->EmitPush(reg); |
| 579 } | 579 } |
| 580 | 580 |
| 581 | 581 |
| 582 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { | 582 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { |
| 583 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; | 583 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; |
| 584 ASSERT(scope()->arguments_shadow() != NULL); | 584 |
| 585 // In strict mode there is no need for shadow arguments. |
| 586 ASSERT(scope()->arguments_shadow() != NULL || scope()->is_strict_mode()); |
| 585 // We don't want to do lazy arguments allocation for functions that | 587 // We don't want to do lazy arguments allocation for functions that |
| 586 // have heap-allocated contexts, because it interfers with the | 588 // have heap-allocated contexts, because it interfers with the |
| 587 // uninitialized const tracking in the context objects. | 589 // uninitialized const tracking in the context objects. |
| 588 return (scope()->num_heap_slots() > 0) | 590 return (scope()->num_heap_slots() > 0 || scope()->is_strict_mode()) |
| 589 ? EAGER_ARGUMENTS_ALLOCATION | 591 ? EAGER_ARGUMENTS_ALLOCATION |
| 590 : LAZY_ARGUMENTS_ALLOCATION; | 592 : LAZY_ARGUMENTS_ALLOCATION; |
| 591 } | 593 } |
| 592 | 594 |
| 593 | 595 |
| 594 void CodeGenerator::StoreArgumentsObject(bool initial) { | 596 void CodeGenerator::StoreArgumentsObject(bool initial) { |
| 595 ArgumentsAllocationMode mode = ArgumentsMode(); | 597 ArgumentsAllocationMode mode = ArgumentsMode(); |
| 596 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); | 598 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); |
| 597 | 599 |
| 598 Comment cmnt(masm_, "[ store arguments object"); | 600 Comment cmnt(masm_, "[ store arguments object"); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 612 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); | 614 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); |
| 613 frame_->Adjust(3); | 615 frame_->Adjust(3); |
| 614 __ Push(r2, r1, r0); | 616 __ Push(r2, r1, r0); |
| 615 frame_->CallStub(&stub, 3); | 617 frame_->CallStub(&stub, 3); |
| 616 frame_->EmitPush(r0); | 618 frame_->EmitPush(r0); |
| 617 } | 619 } |
| 618 | 620 |
| 619 Variable* arguments = scope()->arguments(); | 621 Variable* arguments = scope()->arguments(); |
| 620 Variable* shadow = scope()->arguments_shadow(); | 622 Variable* shadow = scope()->arguments_shadow(); |
| 621 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); | 623 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); |
| 622 ASSERT(shadow != NULL && shadow->AsSlot() != NULL); | 624 ASSERT((shadow != NULL && shadow->AsSlot() != NULL) || |
| 625 scope()->is_strict_mode()); |
| 626 |
| 623 JumpTarget done; | 627 JumpTarget done; |
| 624 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { | 628 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { |
| 625 // We have to skip storing into the arguments slot if it has | 629 // We have to skip storing into the arguments slot if it has |
| 626 // already been written to. This can happen if the a function | 630 // already been written to. This can happen if the a function |
| 627 // has a local variable named 'arguments'. | 631 // has a local variable named 'arguments'. |
| 628 LoadFromSlot(scope()->arguments()->AsSlot(), NOT_INSIDE_TYPEOF); | 632 LoadFromSlot(scope()->arguments()->AsSlot(), NOT_INSIDE_TYPEOF); |
| 629 Register arguments = frame_->PopToRegister(); | 633 Register arguments = frame_->PopToRegister(); |
| 630 __ LoadRoot(ip, Heap::kArgumentsMarkerRootIndex); | 634 __ LoadRoot(ip, Heap::kArgumentsMarkerRootIndex); |
| 631 __ cmp(arguments, ip); | 635 __ cmp(arguments, ip); |
| 632 done.Branch(ne); | 636 done.Branch(ne); |
| 633 } | 637 } |
| 634 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); | 638 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); |
| 635 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); | 639 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); |
| 636 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); | 640 if (shadow != NULL) { |
| 641 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); |
| 642 } |
| 637 } | 643 } |
| 638 | 644 |
| 639 | 645 |
| 640 void CodeGenerator::LoadTypeofExpression(Expression* expr) { | 646 void CodeGenerator::LoadTypeofExpression(Expression* expr) { |
| 641 // Special handling of identifiers as subexpressions of typeof. | 647 // Special handling of identifiers as subexpressions of typeof. |
| 642 Variable* variable = expr->AsVariableProxy()->AsVariable(); | 648 Variable* variable = expr->AsVariableProxy()->AsVariable(); |
| 643 if (variable != NULL && !variable->is_this() && variable->is_global()) { | 649 if (variable != NULL && !variable->is_this() && variable->is_global()) { |
| 644 // For a global variable we build the property reference | 650 // For a global variable we build the property reference |
| 645 // <global>.<variable> and perform a (regular non-contextual) property | 651 // <global>.<variable> and perform a (regular non-contextual) property |
| 646 // load to make sure we do not get reference errors. | 652 // load to make sure we do not get reference errors. |
| (...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1935 } | 1941 } |
| 1936 node->break_target()->Unuse(); | 1942 node->break_target()->Unuse(); |
| 1937 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 1943 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
| 1938 } | 1944 } |
| 1939 | 1945 |
| 1940 | 1946 |
| 1941 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1947 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 1942 frame_->EmitPush(cp); | 1948 frame_->EmitPush(cp); |
| 1943 frame_->EmitPush(Operand(pairs)); | 1949 frame_->EmitPush(Operand(pairs)); |
| 1944 frame_->EmitPush(Operand(Smi::FromInt(is_eval() ? 1 : 0))); | 1950 frame_->EmitPush(Operand(Smi::FromInt(is_eval() ? 1 : 0))); |
| 1951 frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag()))); |
| 1945 | 1952 |
| 1946 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); | 1953 frame_->CallRuntime(Runtime::kDeclareGlobals, 4); |
| 1947 // The result is discarded. | 1954 // The result is discarded. |
| 1948 } | 1955 } |
| 1949 | 1956 |
| 1950 | 1957 |
| 1951 void CodeGenerator::VisitDeclaration(Declaration* node) { | 1958 void CodeGenerator::VisitDeclaration(Declaration* node) { |
| 1952 #ifdef DEBUG | 1959 #ifdef DEBUG |
| 1953 int original_height = frame_->height(); | 1960 int original_height = frame_->height(); |
| 1954 #endif | 1961 #endif |
| 1955 Comment cmnt(masm_, "[ Declaration"); | 1962 Comment cmnt(masm_, "[ Declaration"); |
| 1956 Variable* var = node->proxy()->var(); | 1963 Variable* var = node->proxy()->var(); |
| (...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3284 // context slot declaration, but we cannot initialize it at the | 3291 // context slot declaration, but we cannot initialize it at the |
| 3285 // same time, because the const declaration may be at the end of | 3292 // same time, because the const declaration may be at the end of |
| 3286 // the eval code (sigh...) and the const variable may have been | 3293 // the eval code (sigh...) and the const variable may have been |
| 3287 // used before (where its value is 'undefined'). Thus, we can only | 3294 // used before (where its value is 'undefined'). Thus, we can only |
| 3288 // do the initialization when we actually encounter the expression | 3295 // do the initialization when we actually encounter the expression |
| 3289 // and when the expression operands are defined and valid, and | 3296 // and when the expression operands are defined and valid, and |
| 3290 // thus we need the split into 2 operations: declaration of the | 3297 // thus we need the split into 2 operations: declaration of the |
| 3291 // context slot followed by initialization. | 3298 // context slot followed by initialization. |
| 3292 frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 3299 frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
| 3293 } else { | 3300 } else { |
| 3294 frame_->CallRuntime(Runtime::kStoreContextSlot, 3); | 3301 frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag()))); |
| 3302 frame_->CallRuntime(Runtime::kStoreContextSlot, 4); |
| 3295 } | 3303 } |
| 3296 // Storing a variable must keep the (new) value on the expression | 3304 // Storing a variable must keep the (new) value on the expression |
| 3297 // stack. This is necessary for compiling assignment expressions. | 3305 // stack. This is necessary for compiling assignment expressions. |
| 3298 frame_->EmitPush(r0); | 3306 frame_->EmitPush(r0); |
| 3299 | 3307 |
| 3300 } else { | 3308 } else { |
| 3301 ASSERT(!slot->var()->is_dynamic()); | 3309 ASSERT(!slot->var()->is_dynamic()); |
| 3302 Register scratch = VirtualFrame::scratch0(); | 3310 Register scratch = VirtualFrame::scratch0(); |
| 3303 Register scratch2 = VirtualFrame::scratch1(); | 3311 Register scratch2 = VirtualFrame::scratch1(); |
| 3304 | 3312 |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3636 frame_->Drop(); | 3644 frame_->Drop(); |
| 3637 } | 3645 } |
| 3638 break; | 3646 break; |
| 3639 } | 3647 } |
| 3640 // else fall through | 3648 // else fall through |
| 3641 case ObjectLiteral::Property::PROTOTYPE: { | 3649 case ObjectLiteral::Property::PROTOTYPE: { |
| 3642 frame_->Dup(); | 3650 frame_->Dup(); |
| 3643 Load(key); | 3651 Load(key); |
| 3644 Load(value); | 3652 Load(value); |
| 3645 if (property->emit_store()) { | 3653 if (property->emit_store()) { |
| 3646 frame_->CallRuntime(Runtime::kSetProperty, 3); | 3654 frame_->EmitPush(Operand(Smi::FromInt(NONE))); // PropertyAttributes |
| 3655 frame_->CallRuntime(Runtime::kSetProperty, 4); |
| 3647 } else { | 3656 } else { |
| 3648 frame_->Drop(3); | 3657 frame_->Drop(3); |
| 3649 } | 3658 } |
| 3650 break; | 3659 break; |
| 3651 } | 3660 } |
| 3652 case ObjectLiteral::Property::SETTER: { | 3661 case ObjectLiteral::Property::SETTER: { |
| 3653 frame_->Dup(); | 3662 frame_->Dup(); |
| 3654 Load(key); | 3663 Load(key); |
| 3655 frame_->EmitPush(Operand(Smi::FromInt(1))); | 3664 frame_->EmitPush(Operand(Smi::FromInt(1))); |
| 3656 Load(value); | 3665 Load(value); |
| (...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5173 __ ldr(scratch2_, | 5182 __ ldr(scratch2_, |
| 5174 FieldMemOperand(scratch2_, GlobalObject::kGlobalContextOffset)); | 5183 FieldMemOperand(scratch2_, GlobalObject::kGlobalContextOffset)); |
| 5175 __ ldr(scratch2_, | 5184 __ ldr(scratch2_, |
| 5176 ContextOperand( | 5185 ContextOperand( |
| 5177 scratch2_, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); | 5186 scratch2_, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); |
| 5178 __ cmp(scratch1_, scratch2_); | 5187 __ cmp(scratch1_, scratch2_); |
| 5179 __ b(ne, &false_result); | 5188 __ b(ne, &false_result); |
| 5180 | 5189 |
| 5181 // Set the bit in the map to indicate that it has been checked safe for | 5190 // Set the bit in the map to indicate that it has been checked safe for |
| 5182 // default valueOf and set true result. | 5191 // default valueOf and set true result. |
| 5183 __ ldr(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset)); | 5192 __ ldrb(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset)); |
| 5184 __ orr(scratch1_, | 5193 __ orr(scratch1_, |
| 5185 scratch1_, | 5194 scratch1_, |
| 5186 Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | 5195 Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); |
| 5187 __ str(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset)); | 5196 __ strb(scratch1_, FieldMemOperand(map_result_, Map::kBitField2Offset)); |
| 5188 __ mov(map_result_, Operand(1)); | 5197 __ mov(map_result_, Operand(1)); |
| 5189 __ jmp(exit_label()); | 5198 __ jmp(exit_label()); |
| 5190 __ bind(&false_result); | 5199 __ bind(&false_result); |
| 5191 // Set false result. | 5200 // Set false result. |
| 5192 __ mov(map_result_, Operand(0, RelocInfo::NONE)); | 5201 __ mov(map_result_, Operand(0, RelocInfo::NONE)); |
| 5193 } | 5202 } |
| 5194 | 5203 |
| 5195 private: | 5204 private: |
| 5196 Register object_; | 5205 Register object_; |
| 5197 Register map_result_; | 5206 Register map_result_; |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5578 frame_->EmitPop(index2); | 5587 frame_->EmitPop(index2); |
| 5579 frame_->EmitPop(index1); | 5588 frame_->EmitPop(index1); |
| 5580 frame_->EmitPop(object); | 5589 frame_->EmitPop(object); |
| 5581 | 5590 |
| 5582 DeferredSwapElements* deferred = | 5591 DeferredSwapElements* deferred = |
| 5583 new DeferredSwapElements(object, index1, index2); | 5592 new DeferredSwapElements(object, index1, index2); |
| 5584 | 5593 |
| 5585 // Fetch the map and check if array is in fast case. | 5594 // Fetch the map and check if array is in fast case. |
| 5586 // Check that object doesn't require security checks and | 5595 // Check that object doesn't require security checks and |
| 5587 // has no indexed interceptor. | 5596 // has no indexed interceptor. |
| 5588 __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE); | 5597 __ CompareObjectType(object, tmp1, tmp2, JS_ARRAY_TYPE); |
| 5589 deferred->Branch(lt); | 5598 deferred->Branch(ne); |
| 5590 __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset)); | 5599 __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset)); |
| 5591 __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask)); | 5600 __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask)); |
| 5592 deferred->Branch(ne); | 5601 deferred->Branch(ne); |
| 5593 | 5602 |
| 5594 // Check the object's elements are in fast case and writable. | 5603 // Check the object's elements are in fast case and writable. |
| 5595 __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset)); | 5604 __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset)); |
| 5596 __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset)); | 5605 __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset)); |
| 5597 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); | 5606 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
| 5598 __ cmp(tmp2, ip); | 5607 __ cmp(tmp2, ip); |
| 5599 deferred->Branch(ne); | 5608 deferred->Branch(ne); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5661 Load(args->at(n_args + 1)); // function | 5670 Load(args->at(n_args + 1)); // function |
| 5662 frame_->CallJSFunction(n_args); | 5671 frame_->CallJSFunction(n_args); |
| 5663 frame_->EmitPush(r0); | 5672 frame_->EmitPush(r0); |
| 5664 } | 5673 } |
| 5665 | 5674 |
| 5666 | 5675 |
| 5667 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { | 5676 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) { |
| 5668 ASSERT_EQ(args->length(), 1); | 5677 ASSERT_EQ(args->length(), 1); |
| 5669 Load(args->at(0)); | 5678 Load(args->at(0)); |
| 5670 if (CpuFeatures::IsSupported(VFP3)) { | 5679 if (CpuFeatures::IsSupported(VFP3)) { |
| 5671 TranscendentalCacheStub stub(TranscendentalCache::SIN); | 5680 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
| 5681 TranscendentalCacheStub::TAGGED); |
| 5672 frame_->SpillAllButCopyTOSToR0(); | 5682 frame_->SpillAllButCopyTOSToR0(); |
| 5673 frame_->CallStub(&stub, 1); | 5683 frame_->CallStub(&stub, 1); |
| 5674 } else { | 5684 } else { |
| 5675 frame_->CallRuntime(Runtime::kMath_sin, 1); | 5685 frame_->CallRuntime(Runtime::kMath_sin, 1); |
| 5676 } | 5686 } |
| 5677 frame_->EmitPush(r0); | 5687 frame_->EmitPush(r0); |
| 5678 } | 5688 } |
| 5679 | 5689 |
| 5680 | 5690 |
| 5681 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { | 5691 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { |
| 5682 ASSERT_EQ(args->length(), 1); | 5692 ASSERT_EQ(args->length(), 1); |
| 5683 Load(args->at(0)); | 5693 Load(args->at(0)); |
| 5684 if (CpuFeatures::IsSupported(VFP3)) { | 5694 if (CpuFeatures::IsSupported(VFP3)) { |
| 5685 TranscendentalCacheStub stub(TranscendentalCache::COS); | 5695 TranscendentalCacheStub stub(TranscendentalCache::COS, |
| 5696 TranscendentalCacheStub::TAGGED); |
| 5686 frame_->SpillAllButCopyTOSToR0(); | 5697 frame_->SpillAllButCopyTOSToR0(); |
| 5687 frame_->CallStub(&stub, 1); | 5698 frame_->CallStub(&stub, 1); |
| 5688 } else { | 5699 } else { |
| 5689 frame_->CallRuntime(Runtime::kMath_cos, 1); | 5700 frame_->CallRuntime(Runtime::kMath_cos, 1); |
| 5690 } | 5701 } |
| 5691 frame_->EmitPush(r0); | 5702 frame_->EmitPush(r0); |
| 5692 } | 5703 } |
| 5693 | 5704 |
| 5694 | 5705 |
| 5695 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) { | 5706 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) { |
| 5696 ASSERT_EQ(args->length(), 1); | 5707 ASSERT_EQ(args->length(), 1); |
| 5697 Load(args->at(0)); | 5708 Load(args->at(0)); |
| 5698 if (CpuFeatures::IsSupported(VFP3)) { | 5709 if (CpuFeatures::IsSupported(VFP3)) { |
| 5699 TranscendentalCacheStub stub(TranscendentalCache::LOG); | 5710 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 5711 TranscendentalCacheStub::TAGGED); |
| 5700 frame_->SpillAllButCopyTOSToR0(); | 5712 frame_->SpillAllButCopyTOSToR0(); |
| 5701 frame_->CallStub(&stub, 1); | 5713 frame_->CallStub(&stub, 1); |
| 5702 } else { | 5714 } else { |
| 5703 frame_->CallRuntime(Runtime::kMath_log, 1); | 5715 frame_->CallRuntime(Runtime::kMath_log, 1); |
| 5704 } | 5716 } |
| 5705 frame_->EmitPush(r0); | 5717 frame_->EmitPush(r0); |
| 5706 } | 5718 } |
| 5707 | 5719 |
| 5708 | 5720 |
| 5709 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { | 5721 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5855 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); | 5867 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); |
| 5856 if (property != NULL) { | 5868 if (property != NULL) { |
| 5857 Load(property->obj()); | 5869 Load(property->obj()); |
| 5858 Load(property->key()); | 5870 Load(property->key()); |
| 5859 frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag()))); | 5871 frame_->EmitPush(Operand(Smi::FromInt(strict_mode_flag()))); |
| 5860 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 3); | 5872 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 3); |
| 5861 frame_->EmitPush(r0); | 5873 frame_->EmitPush(r0); |
| 5862 | 5874 |
| 5863 } else if (variable != NULL) { | 5875 } else if (variable != NULL) { |
| 5864 // Delete of an unqualified identifier is disallowed in strict mode | 5876 // Delete of an unqualified identifier is disallowed in strict mode |
| 5865 // so this code can only be reached in non-strict mode. | 5877 // but "delete this" is. |
| 5866 ASSERT(strict_mode_flag() == kNonStrictMode); | 5878 ASSERT(strict_mode_flag() == kNonStrictMode || variable->is_this()); |
| 5867 Slot* slot = variable->AsSlot(); | 5879 Slot* slot = variable->AsSlot(); |
| 5868 if (variable->is_global()) { | 5880 if (variable->is_global()) { |
| 5869 LoadGlobal(); | 5881 LoadGlobal(); |
| 5870 frame_->EmitPush(Operand(variable->name())); | 5882 frame_->EmitPush(Operand(variable->name())); |
| 5871 frame_->EmitPush(Operand(Smi::FromInt(kNonStrictMode))); | 5883 frame_->EmitPush(Operand(Smi::FromInt(kNonStrictMode))); |
| 5872 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 3); | 5884 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, 3); |
| 5873 frame_->EmitPush(r0); | 5885 frame_->EmitPush(r0); |
| 5874 | 5886 |
| 5875 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 5887 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 5876 // Delete from the context holding the named variable. | 5888 // Delete from the context holding the named variable. |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6679 // deferred code. | 6691 // deferred code. |
| 6680 __ BlockConstPoolFor(1); | 6692 __ BlockConstPoolFor(1); |
| 6681 } | 6693 } |
| 6682 } | 6694 } |
| 6683 | 6695 |
| 6684 | 6696 |
| 6685 class DeferredReferenceSetKeyedValue: public DeferredCode { | 6697 class DeferredReferenceSetKeyedValue: public DeferredCode { |
| 6686 public: | 6698 public: |
| 6687 DeferredReferenceSetKeyedValue(Register value, | 6699 DeferredReferenceSetKeyedValue(Register value, |
| 6688 Register key, | 6700 Register key, |
| 6689 Register receiver) | 6701 Register receiver, |
| 6690 : value_(value), key_(key), receiver_(receiver) { | 6702 StrictModeFlag strict_mode) |
| 6703 : value_(value), |
| 6704 key_(key), |
| 6705 receiver_(receiver), |
| 6706 strict_mode_(strict_mode) { |
| 6691 set_comment("[ DeferredReferenceSetKeyedValue"); | 6707 set_comment("[ DeferredReferenceSetKeyedValue"); |
| 6692 } | 6708 } |
| 6693 | 6709 |
| 6694 virtual void Generate(); | 6710 virtual void Generate(); |
| 6695 | 6711 |
| 6696 private: | 6712 private: |
| 6697 Register value_; | 6713 Register value_; |
| 6698 Register key_; | 6714 Register key_; |
| 6699 Register receiver_; | 6715 Register receiver_; |
| 6716 StrictModeFlag strict_mode_; |
| 6700 }; | 6717 }; |
| 6701 | 6718 |
| 6702 | 6719 |
| 6703 void DeferredReferenceSetKeyedValue::Generate() { | 6720 void DeferredReferenceSetKeyedValue::Generate() { |
| 6704 Register scratch1 = VirtualFrame::scratch0(); | 6721 Register scratch1 = VirtualFrame::scratch0(); |
| 6705 Register scratch2 = VirtualFrame::scratch1(); | 6722 Register scratch2 = VirtualFrame::scratch1(); |
| 6706 __ DecrementCounter(&Counters::keyed_store_inline, 1, scratch1, scratch2); | 6723 __ DecrementCounter(&Counters::keyed_store_inline, 1, scratch1, scratch2); |
| 6707 __ IncrementCounter( | 6724 __ IncrementCounter( |
| 6708 &Counters::keyed_store_inline_miss, 1, scratch1, scratch2); | 6725 &Counters::keyed_store_inline_miss, 1, scratch1, scratch2); |
| 6709 | 6726 |
| 6710 // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic | 6727 // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic |
| 6711 // calling convention. | 6728 // calling convention. |
| 6712 if (value_.is(r1)) { | 6729 if (value_.is(r1)) { |
| 6713 __ Swap(r0, r1, ip); | 6730 __ Swap(r0, r1, ip); |
| 6714 } | 6731 } |
| 6715 ASSERT(receiver_.is(r2)); | 6732 ASSERT(receiver_.is(r2)); |
| 6716 | 6733 |
| 6717 // The rest of the instructions in the deferred code must be together. | 6734 // The rest of the instructions in the deferred code must be together. |
| 6718 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 6735 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
| 6719 // Call keyed store IC. It has the arguments value, key and receiver in r0, | 6736 // Call keyed store IC. It has the arguments value, key and receiver in r0, |
| 6720 // r1 and r2. | 6737 // r1 and r2. |
| 6721 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 6738 Handle<Code> ic(Builtins::builtin( |
| 6739 (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict |
| 6740 : Builtins::KeyedStoreIC_Initialize)); |
| 6722 __ Call(ic, RelocInfo::CODE_TARGET); | 6741 __ Call(ic, RelocInfo::CODE_TARGET); |
| 6723 // The call must be followed by a nop instruction to indicate that the | 6742 // The call must be followed by a nop instruction to indicate that the |
| 6724 // keyed store has been inlined. | 6743 // keyed store has been inlined. |
| 6725 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); | 6744 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); |
| 6726 | 6745 |
| 6727 // Block the constant pool for one more instruction after leaving this | 6746 // Block the constant pool for one more instruction after leaving this |
| 6728 // constant pool block scope to include the branch instruction ending the | 6747 // constant pool block scope to include the branch instruction ending the |
| 6729 // deferred code. | 6748 // deferred code. |
| 6730 __ BlockConstPoolFor(1); | 6749 __ BlockConstPoolFor(1); |
| 6731 } | 6750 } |
| 6732 } | 6751 } |
| 6733 | 6752 |
| 6734 | 6753 |
| 6735 class DeferredReferenceSetNamedValue: public DeferredCode { | 6754 class DeferredReferenceSetNamedValue: public DeferredCode { |
| 6736 public: | 6755 public: |
| 6737 DeferredReferenceSetNamedValue(Register value, | 6756 DeferredReferenceSetNamedValue(Register value, |
| 6738 Register receiver, | 6757 Register receiver, |
| 6739 Handle<String> name) | 6758 Handle<String> name, |
| 6740 : value_(value), receiver_(receiver), name_(name) { | 6759 StrictModeFlag strict_mode) |
| 6760 : value_(value), |
| 6761 receiver_(receiver), |
| 6762 name_(name), |
| 6763 strict_mode_(strict_mode) { |
| 6741 set_comment("[ DeferredReferenceSetNamedValue"); | 6764 set_comment("[ DeferredReferenceSetNamedValue"); |
| 6742 } | 6765 } |
| 6743 | 6766 |
| 6744 virtual void Generate(); | 6767 virtual void Generate(); |
| 6745 | 6768 |
| 6746 private: | 6769 private: |
| 6747 Register value_; | 6770 Register value_; |
| 6748 Register receiver_; | 6771 Register receiver_; |
| 6749 Handle<String> name_; | 6772 Handle<String> name_; |
| 6773 StrictModeFlag strict_mode_; |
| 6750 }; | 6774 }; |
| 6751 | 6775 |
| 6752 | 6776 |
| 6753 // Takes value in r0, receiver in r1 and returns the result (the | 6777 // Takes value in r0, receiver in r1 and returns the result (the |
| 6754 // value) in r0. | 6778 // value) in r0. |
| 6755 void DeferredReferenceSetNamedValue::Generate() { | 6779 void DeferredReferenceSetNamedValue::Generate() { |
| 6756 // Record the entry frame and spill. | 6780 // Record the entry frame and spill. |
| 6757 VirtualFrame copied_frame(*frame_state()->frame()); | 6781 VirtualFrame copied_frame(*frame_state()->frame()); |
| 6758 copied_frame.SpillAll(); | 6782 copied_frame.SpillAll(); |
| 6759 | 6783 |
| 6760 // Ensure value in r0, receiver in r1 to match store ic calling | 6784 // Ensure value in r0, receiver in r1 to match store ic calling |
| 6761 // convention. | 6785 // convention. |
| 6762 ASSERT(value_.is(r0) && receiver_.is(r1)); | 6786 ASSERT(value_.is(r0) && receiver_.is(r1)); |
| 6763 __ mov(r2, Operand(name_)); | 6787 __ mov(r2, Operand(name_)); |
| 6764 | 6788 |
| 6765 // The rest of the instructions in the deferred code must be together. | 6789 // The rest of the instructions in the deferred code must be together. |
| 6766 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 6790 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
| 6767 // Call keyed store IC. It has the arguments value, key and receiver in r0, | 6791 // Call keyed store IC. It has the arguments value, key and receiver in r0, |
| 6768 // r1 and r2. | 6792 // r1 and r2. |
| 6769 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 6793 Handle<Code> ic(Builtins::builtin( |
| 6794 (strict_mode_ == kStrictMode) ? Builtins::StoreIC_Initialize_Strict |
| 6795 : Builtins::StoreIC_Initialize)); |
| 6770 __ Call(ic, RelocInfo::CODE_TARGET); | 6796 __ Call(ic, RelocInfo::CODE_TARGET); |
| 6771 // The call must be followed by a nop instruction to indicate that the | 6797 // The call must be followed by a nop instruction to indicate that the |
| 6772 // named store has been inlined. | 6798 // named store has been inlined. |
| 6773 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); | 6799 __ MarkCode(MacroAssembler::PROPERTY_ACCESS_INLINED); |
| 6774 | 6800 |
| 6775 // Go back to the frame we entered with. The instructions | 6801 // Go back to the frame we entered with. The instructions |
| 6776 // generated by this merge are skipped over by the inline store | 6802 // generated by this merge are skipped over by the inline store |
| 6777 // patching mechanism when looking for the branch instruction that | 6803 // patching mechanism when looking for the branch instruction that |
| 6778 // tells it where the code to patch is. | 6804 // tells it where the code to patch is. |
| 6779 copied_frame.MergeTo(frame_state()->frame()); | 6805 copied_frame.MergeTo(frame_state()->frame()); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6948 // Inline the in-object property case. | 6974 // Inline the in-object property case. |
| 6949 JumpTarget slow, done; | 6975 JumpTarget slow, done; |
| 6950 | 6976 |
| 6951 // Get the value and receiver from the stack. | 6977 // Get the value and receiver from the stack. |
| 6952 frame()->PopToR0(); | 6978 frame()->PopToR0(); |
| 6953 Register value = r0; | 6979 Register value = r0; |
| 6954 frame()->PopToR1(); | 6980 frame()->PopToR1(); |
| 6955 Register receiver = r1; | 6981 Register receiver = r1; |
| 6956 | 6982 |
| 6957 DeferredReferenceSetNamedValue* deferred = | 6983 DeferredReferenceSetNamedValue* deferred = |
| 6958 new DeferredReferenceSetNamedValue(value, receiver, name); | 6984 new DeferredReferenceSetNamedValue( |
| 6985 value, receiver, name, strict_mode_flag()); |
| 6959 | 6986 |
| 6960 // Check that the receiver is a heap object. | 6987 // Check that the receiver is a heap object. |
| 6961 __ tst(receiver, Operand(kSmiTagMask)); | 6988 __ tst(receiver, Operand(kSmiTagMask)); |
| 6962 deferred->Branch(eq); | 6989 deferred->Branch(eq); |
| 6963 | 6990 |
| 6964 // The following instructions are the part of the inlined | 6991 // The following instructions are the part of the inlined |
| 6965 // in-object property store code which can be patched. Therefore | 6992 // in-object property store code which can be patched. Therefore |
| 6966 // the exact number of instructions generated must be fixed, so | 6993 // the exact number of instructions generated must be fixed, so |
| 6967 // the constant pool is blocked while generating this code. | 6994 // the constant pool is blocked while generating this code. |
| 6968 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 6995 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7119 Register scratch1 = VirtualFrame::scratch0(); | 7146 Register scratch1 = VirtualFrame::scratch0(); |
| 7120 Register scratch2 = VirtualFrame::scratch1(); | 7147 Register scratch2 = VirtualFrame::scratch1(); |
| 7121 Register scratch3 = r3; | 7148 Register scratch3 = r3; |
| 7122 | 7149 |
| 7123 // Counter will be decremented in the deferred code. Placed here to avoid | 7150 // Counter will be decremented in the deferred code. Placed here to avoid |
| 7124 // having it in the instruction stream below where patching will occur. | 7151 // having it in the instruction stream below where patching will occur. |
| 7125 __ IncrementCounter(&Counters::keyed_store_inline, 1, | 7152 __ IncrementCounter(&Counters::keyed_store_inline, 1, |
| 7126 scratch1, scratch2); | 7153 scratch1, scratch2); |
| 7127 | 7154 |
| 7128 | 7155 |
| 7129 | |
| 7130 // Load the value, key and receiver from the stack. | 7156 // Load the value, key and receiver from the stack. |
| 7131 bool value_is_harmless = frame_->KnownSmiAt(0); | 7157 bool value_is_harmless = frame_->KnownSmiAt(0); |
| 7132 if (wb_info == NEVER_NEWSPACE) value_is_harmless = true; | 7158 if (wb_info == NEVER_NEWSPACE) value_is_harmless = true; |
| 7133 bool key_is_smi = frame_->KnownSmiAt(1); | 7159 bool key_is_smi = frame_->KnownSmiAt(1); |
| 7134 Register value = frame_->PopToRegister(); | 7160 Register value = frame_->PopToRegister(); |
| 7135 Register key = frame_->PopToRegister(value); | 7161 Register key = frame_->PopToRegister(value); |
| 7136 VirtualFrame::SpilledScope spilled(frame_); | 7162 VirtualFrame::SpilledScope spilled(frame_); |
| 7137 Register receiver = r2; | 7163 Register receiver = r2; |
| 7138 frame_->EmitPop(receiver); | 7164 frame_->EmitPop(receiver); |
| 7139 | 7165 |
| 7140 #ifdef DEBUG | 7166 #ifdef DEBUG |
| 7141 bool we_remembered_the_write_barrier = value_is_harmless; | 7167 bool we_remembered_the_write_barrier = value_is_harmless; |
| 7142 #endif | 7168 #endif |
| 7143 | 7169 |
| 7144 // The deferred code expects value, key and receiver in registers. | 7170 // The deferred code expects value, key and receiver in registers. |
| 7145 DeferredReferenceSetKeyedValue* deferred = | 7171 DeferredReferenceSetKeyedValue* deferred = |
| 7146 new DeferredReferenceSetKeyedValue(value, key, receiver); | 7172 new DeferredReferenceSetKeyedValue( |
| 7173 value, key, receiver, strict_mode_flag()); |
| 7147 | 7174 |
| 7148 // Check that the value is a smi. As this inlined code does not set the | 7175 // Check that the value is a smi. As this inlined code does not set the |
| 7149 // write barrier it is only possible to store smi values. | 7176 // write barrier it is only possible to store smi values. |
| 7150 if (!value_is_harmless) { | 7177 if (!value_is_harmless) { |
| 7151 // If the value is not likely to be a Smi then let's test the fixed array | 7178 // If the value is not likely to be a Smi then let's test the fixed array |
| 7152 // for new space instead. See below. | 7179 // for new space instead. See below. |
| 7153 if (wb_info == LIKELY_SMI) { | 7180 if (wb_info == LIKELY_SMI) { |
| 7154 __ tst(value, Operand(kSmiTagMask)); | 7181 __ tst(value, Operand(kSmiTagMask)); |
| 7155 deferred->Branch(ne); | 7182 deferred->Branch(ne); |
| 7156 #ifdef DEBUG | 7183 #ifdef DEBUG |
| 7157 we_remembered_the_write_barrier = true; | 7184 we_remembered_the_write_barrier = true; |
| 7158 #endif | 7185 #endif |
| 7159 } | 7186 } |
| 7160 } | 7187 } |
| 7161 | 7188 |
| 7162 if (!key_is_smi) { | 7189 if (!key_is_smi) { |
| 7163 // Check that the key is a smi. | 7190 // Check that the key is a smi. |
| 7164 __ tst(key, Operand(kSmiTagMask)); | 7191 __ tst(key, Operand(kSmiTagMask)); |
| 7165 deferred->Branch(ne); | 7192 deferred->Branch(ne); |
| 7166 } | 7193 } |
| 7167 | 7194 |
| 7168 // Check that the receiver is a heap object. | 7195 // Check that the receiver is a heap object. |
| 7169 __ tst(receiver, Operand(kSmiTagMask)); | 7196 __ tst(receiver, Operand(kSmiTagMask)); |
| 7170 deferred->Branch(eq); | 7197 deferred->Branch(eq); |
| 7171 | 7198 |
| 7172 // Check that the receiver is a JSArray. | 7199 // Check that the receiver is a JSArray. |
| 7173 __ CompareObjectType(receiver, scratch1, scratch1, JS_ARRAY_TYPE); | 7200 __ CompareObjectType(receiver, scratch1, scratch1, JS_ARRAY_TYPE); |
| 7174 deferred->Branch(ne); | 7201 deferred->Branch(ne); |
| 7175 | 7202 |
| 7176 // Check that the key is within bounds. Both the key and the length of | |
| 7177 // the JSArray are smis. Use unsigned comparison to handle negative keys. | |
| 7178 __ ldr(scratch1, FieldMemOperand(receiver, JSArray::kLengthOffset)); | |
| 7179 __ cmp(scratch1, key); | |
| 7180 deferred->Branch(ls); // Unsigned less equal. | |
| 7181 | |
| 7182 // Get the elements array from the receiver. | 7203 // Get the elements array from the receiver. |
| 7183 __ ldr(scratch1, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 7204 __ ldr(scratch1, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
| 7184 if (!value_is_harmless && wb_info != LIKELY_SMI) { | 7205 if (!value_is_harmless && wb_info != LIKELY_SMI) { |
| 7185 Label ok; | 7206 Label ok; |
| 7186 __ and_(scratch2, scratch1, Operand(ExternalReference::new_space_mask())); | 7207 __ and_(scratch2, scratch1, Operand(ExternalReference::new_space_mask())); |
| 7187 __ cmp(scratch2, Operand(ExternalReference::new_space_start())); | 7208 __ cmp(scratch2, Operand(ExternalReference::new_space_start())); |
| 7188 __ tst(value, Operand(kSmiTagMask), ne); | 7209 __ tst(value, Operand(kSmiTagMask), ne); |
| 7189 deferred->Branch(ne); | 7210 deferred->Branch(ne); |
| 7190 #ifdef DEBUG | 7211 #ifdef DEBUG |
| 7191 we_remembered_the_write_barrier = true; | 7212 we_remembered_the_write_barrier = true; |
| 7192 #endif | 7213 #endif |
| 7193 } | 7214 } |
| 7194 // Check that the elements array is not a dictionary. | 7215 // Check that the elements array is not a dictionary. |
| 7195 __ ldr(scratch2, FieldMemOperand(scratch1, JSObject::kMapOffset)); | 7216 __ ldr(scratch2, FieldMemOperand(scratch1, JSObject::kMapOffset)); |
| 7217 |
| 7196 // The following instructions are the part of the inlined store keyed | 7218 // The following instructions are the part of the inlined store keyed |
| 7197 // property code which can be patched. Therefore the exact number of | 7219 // property code which can be patched. Therefore the exact number of |
| 7198 // instructions generated need to be fixed, so the constant pool is blocked | 7220 // instructions generated need to be fixed, so the constant pool is blocked |
| 7199 // while generating this code. | 7221 // while generating this code. |
| 7200 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 7222 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
| 7201 #ifdef DEBUG | 7223 #ifdef DEBUG |
| 7202 Label check_inlined_codesize; | 7224 Label check_inlined_codesize; |
| 7203 masm_->bind(&check_inlined_codesize); | 7225 masm_->bind(&check_inlined_codesize); |
| 7204 #endif | 7226 #endif |
| 7205 | 7227 |
| 7206 // Read the fixed array map from the constant pool (not from the root | 7228 // Read the fixed array map from the constant pool (not from the root |
| 7207 // array) so that the value can be patched. When debugging, we patch this | 7229 // array) so that the value can be patched. When debugging, we patch this |
| 7208 // comparison to always fail so that we will hit the IC call in the | 7230 // comparison to always fail so that we will hit the IC call in the |
| 7209 // deferred code which will allow the debugger to break for fast case | 7231 // deferred code which will allow the debugger to break for fast case |
| 7210 // stores. | 7232 // stores. |
| 7211 __ mov(scratch3, Operand(Factory::fixed_array_map())); | 7233 __ mov(scratch3, Operand(Factory::fixed_array_map())); |
| 7212 __ cmp(scratch2, scratch3); | 7234 __ cmp(scratch2, scratch3); |
| 7213 deferred->Branch(ne); | 7235 deferred->Branch(ne); |
| 7214 | 7236 |
| 7237 // Check that the key is within bounds. Both the key and the length of |
| 7238 // the JSArray are smis (because the fixed array check above ensures the |
| 7239 // elements are in fast case). Use unsigned comparison to handle negative |
| 7240 // keys. |
| 7241 __ ldr(scratch3, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 7242 __ cmp(scratch3, key); |
| 7243 deferred->Branch(ls); // Unsigned less equal. |
| 7244 |
| 7215 // Store the value. | 7245 // Store the value. |
| 7216 __ add(scratch1, scratch1, | 7246 __ add(scratch1, scratch1, |
| 7217 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 7247 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 7218 __ str(value, | 7248 __ str(value, |
| 7219 MemOperand(scratch1, key, LSL, | 7249 MemOperand(scratch1, key, LSL, |
| 7220 kPointerSizeLog2 - (kSmiTagSize + kSmiShiftSize))); | 7250 kPointerSizeLog2 - (kSmiTagSize + kSmiShiftSize))); |
| 7221 | 7251 |
| 7222 // Make sure that the expected number of instructions are generated. | 7252 // Make sure that the expected number of instructions are generated. |
| 7223 ASSERT_EQ(kInlinedKeyedStoreInstructionsAfterPatch, | 7253 ASSERT_EQ(kInlinedKeyedStoreInstructionsAfterPatch, |
| 7224 masm_->InstructionsGeneratedSince(&check_inlined_codesize)); | 7254 masm_->InstructionsGeneratedSince(&check_inlined_codesize)); |
| 7225 } | 7255 } |
| 7226 | 7256 |
| 7227 ASSERT(we_remembered_the_write_barrier); | 7257 ASSERT(we_remembered_the_write_barrier); |
| 7228 | 7258 |
| 7229 deferred->BindExit(); | 7259 deferred->BindExit(); |
| 7230 } else { | 7260 } else { |
| 7231 frame()->CallKeyedStoreIC(); | 7261 frame()->CallKeyedStoreIC(strict_mode_flag()); |
| 7232 } | 7262 } |
| 7233 } | 7263 } |
| 7234 | 7264 |
| 7235 | 7265 |
| 7236 #ifdef DEBUG | 7266 #ifdef DEBUG |
| 7237 bool CodeGenerator::HasValidEntryRegisters() { return true; } | 7267 bool CodeGenerator::HasValidEntryRegisters() { return true; } |
| 7238 #endif | 7268 #endif |
| 7239 | 7269 |
| 7240 | 7270 |
| 7241 #undef __ | 7271 #undef __ |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7389 BinaryOpIC::GetName(runtime_operands_type_)); | 7419 BinaryOpIC::GetName(runtime_operands_type_)); |
| 7390 return name_; | 7420 return name_; |
| 7391 } | 7421 } |
| 7392 | 7422 |
| 7393 | 7423 |
| 7394 #undef __ | 7424 #undef __ |
| 7395 | 7425 |
| 7396 } } // namespace v8::internal | 7426 } } // namespace v8::internal |
| 7397 | 7427 |
| 7398 #endif // V8_TARGET_ARCH_ARM | 7428 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |