| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 | 103 |
| 104 #ifdef DEBUG | 104 #ifdef DEBUG |
| 105 if (strlen(FLAG_stop_at) > 0 && | 105 if (strlen(FLAG_stop_at) > 0 && |
| 106 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 106 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
| 107 __ stop("stop_at"); | 107 __ stop("stop_at"); |
| 108 } | 108 } |
| 109 #endif | 109 #endif |
| 110 | 110 |
| 111 // r4: Callee's JS function. | 111 // r4: Callee's JS function. |
| 112 // cp: Callee's context. | 112 // cp: Callee's context. |
| 113 // pp: Callee's constant pool pointer (if FLAG_enable_ool_constant_pool) | 113 // pp: Callee's constant pool pointer (if enabled) |
| 114 // fp: Caller's frame pointer. | 114 // fp: Caller's frame pointer. |
| 115 // lr: Caller's pc. | 115 // lr: Caller's pc. |
| 116 // ip: Our own function entry (required by the prologue) | 116 // ip: Our own function entry (required by the prologue) |
| 117 | 117 |
| 118 // Sloppy mode functions and builtins need to replace the receiver with the | 118 // Sloppy mode functions and builtins need to replace the receiver with the |
| 119 // global proxy when called as functions (without an explicit receiver | 119 // global proxy when called as functions (without an explicit receiver |
| 120 // object). | 120 // object). |
| 121 if (info_->this_has_uses() && is_sloppy(info_->language_mode()) && | 121 if (info_->this_has_uses() && is_sloppy(info_->language_mode()) && |
| 122 !info_->is_native()) { | 122 !info_->is_native()) { |
| 123 Label ok; | 123 Label ok; |
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 Safepoint safepoint = | 935 Safepoint safepoint = |
| 936 safepoints_.DefineSafepoint(masm(), kind, arguments, deopt_mode); | 936 safepoints_.DefineSafepoint(masm(), kind, arguments, deopt_mode); |
| 937 for (int i = 0; i < operands->length(); i++) { | 937 for (int i = 0; i < operands->length(); i++) { |
| 938 LOperand* pointer = operands->at(i); | 938 LOperand* pointer = operands->at(i); |
| 939 if (pointer->IsStackSlot()) { | 939 if (pointer->IsStackSlot()) { |
| 940 safepoint.DefinePointerSlot(pointer->index(), zone()); | 940 safepoint.DefinePointerSlot(pointer->index(), zone()); |
| 941 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { | 941 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { |
| 942 safepoint.DefinePointerRegister(ToRegister(pointer), zone()); | 942 safepoint.DefinePointerRegister(ToRegister(pointer), zone()); |
| 943 } | 943 } |
| 944 } | 944 } |
| 945 #if V8_OOL_CONSTANT_POOL | |
| 946 if (kind & Safepoint::kWithRegisters) { | |
| 947 // Register always contains a pointer to the constant pool. | |
| 948 safepoint.DefinePointerRegister(kConstantPoolRegister, zone()); | |
| 949 } | |
| 950 #endif | |
| 951 } | 945 } |
| 952 | 946 |
| 953 | 947 |
| 954 void LCodeGen::RecordSafepoint(LPointerMap* pointers, | 948 void LCodeGen::RecordSafepoint(LPointerMap* pointers, |
| 955 Safepoint::DeoptMode deopt_mode) { | 949 Safepoint::DeoptMode deopt_mode) { |
| 956 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); | 950 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); |
| 957 } | 951 } |
| 958 | 952 |
| 959 | 953 |
| 960 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { | 954 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { |
| (...skipping 1820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2781 __ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset)); | 2775 __ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 2782 __ lbz(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset)); | 2776 __ lbz(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset)); |
| 2783 __ subi(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2777 __ subi(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2784 __ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - | 2778 __ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - |
| 2785 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2779 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2786 __ bgt(is_false); | 2780 __ bgt(is_false); |
| 2787 } | 2781 } |
| 2788 | 2782 |
| 2789 // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. | 2783 // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. |
| 2790 // Check if the constructor in the map is a function. | 2784 // Check if the constructor in the map is a function. |
| 2791 __ LoadP(temp, FieldMemOperand(temp, Map::kConstructorOffset)); | 2785 Register instance_type = ip; |
| 2786 __ GetMapConstructor(temp, temp, temp2, instance_type); |
| 2792 | 2787 |
| 2793 // Objects with a non-function constructor have class 'Object'. | 2788 // Objects with a non-function constructor have class 'Object'. |
| 2794 __ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE); | 2789 __ cmpi(instance_type, Operand(JS_FUNCTION_TYPE)); |
| 2795 if (class_name->IsOneByteEqualTo(STATIC_CHAR_VECTOR("Object"))) { | 2790 if (class_name->IsOneByteEqualTo(STATIC_CHAR_VECTOR("Object"))) { |
| 2796 __ bne(is_true); | 2791 __ bne(is_true); |
| 2797 } else { | 2792 } else { |
| 2798 __ bne(is_false); | 2793 __ bne(is_false); |
| 2799 } | 2794 } |
| 2800 | 2795 |
| 2801 // temp now contains the constructor function. Grab the | 2796 // temp now contains the constructor function. Grab the |
| 2802 // instance class name from there. | 2797 // instance class name from there. |
| 2803 __ LoadP(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset)); | 2798 __ LoadP(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset)); |
| 2804 __ LoadP(temp, | 2799 __ LoadP(temp, |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3087 DCHECK(ToRegister(instr->context()).is(cp)); | 3082 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3088 DCHECK(ToRegister(instr->global_object()) | 3083 DCHECK(ToRegister(instr->global_object()) |
| 3089 .is(LoadDescriptor::ReceiverRegister())); | 3084 .is(LoadDescriptor::ReceiverRegister())); |
| 3090 DCHECK(ToRegister(instr->result()).is(r3)); | 3085 DCHECK(ToRegister(instr->result()).is(r3)); |
| 3091 | 3086 |
| 3092 __ mov(LoadDescriptor::NameRegister(), Operand(instr->name())); | 3087 __ mov(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| 3093 if (FLAG_vector_ics) { | 3088 if (FLAG_vector_ics) { |
| 3094 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); | 3089 EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); |
| 3095 } | 3090 } |
| 3096 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; | 3091 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; |
| 3097 Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code(); | 3092 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, |
| 3093 PREMONOMORPHIC).code(); |
| 3098 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3094 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3099 } | 3095 } |
| 3100 | 3096 |
| 3101 | 3097 |
| 3102 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { | 3098 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { |
| 3103 Register value = ToRegister(instr->value()); | 3099 Register value = ToRegister(instr->value()); |
| 3104 Register cell = scratch0(); | 3100 Register cell = scratch0(); |
| 3105 | 3101 |
| 3106 // Load the cell. | 3102 // Load the cell. |
| 3107 __ mov(cell, Operand(instr->hydrogen()->cell().handle())); | 3103 __ mov(cell, Operand(instr->hydrogen()->cell().handle())); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3229 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 3225 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 3230 DCHECK(ToRegister(instr->context()).is(cp)); | 3226 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3231 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); | 3227 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); |
| 3232 DCHECK(ToRegister(instr->result()).is(r3)); | 3228 DCHECK(ToRegister(instr->result()).is(r3)); |
| 3233 | 3229 |
| 3234 // Name is always in r5. | 3230 // Name is always in r5. |
| 3235 __ mov(LoadDescriptor::NameRegister(), Operand(instr->name())); | 3231 __ mov(LoadDescriptor::NameRegister(), Operand(instr->name())); |
| 3236 if (FLAG_vector_ics) { | 3232 if (FLAG_vector_ics) { |
| 3237 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); | 3233 EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); |
| 3238 } | 3234 } |
| 3239 Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code(); | 3235 Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( |
| 3236 isolate(), NOT_CONTEXTUAL, |
| 3237 instr->hydrogen()->initialization_state()).code(); |
| 3240 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3238 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3241 } | 3239 } |
| 3242 | 3240 |
| 3243 | 3241 |
| 3244 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 3242 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| 3245 Register scratch = scratch0(); | 3243 Register scratch = scratch0(); |
| 3246 Register function = ToRegister(instr->function()); | 3244 Register function = ToRegister(instr->function()); |
| 3247 Register result = ToRegister(instr->result()); | 3245 Register result = ToRegister(instr->result()); |
| 3248 | 3246 |
| 3249 // Get the prototype or initial map from the function. | 3247 // Get the prototype or initial map from the function. |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3584 | 3582 |
| 3585 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3583 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 3586 DCHECK(ToRegister(instr->context()).is(cp)); | 3584 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3587 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); | 3585 DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); |
| 3588 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister())); | 3586 DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister())); |
| 3589 | 3587 |
| 3590 if (FLAG_vector_ics) { | 3588 if (FLAG_vector_ics) { |
| 3591 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); | 3589 EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); |
| 3592 } | 3590 } |
| 3593 | 3591 |
| 3594 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 3592 Handle<Code> ic = |
| 3593 CodeFactory::KeyedLoadICInOptimizedCode( |
| 3594 isolate(), instr->hydrogen()->initialization_state()).code(); |
| 3595 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3595 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3596 } | 3596 } |
| 3597 | 3597 |
| 3598 | 3598 |
| 3599 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 3599 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
| 3600 Register scratch = scratch0(); | 3600 Register scratch = scratch0(); |
| 3601 Register result = ToRegister(instr->result()); | 3601 Register result = ToRegister(instr->result()); |
| 3602 | 3602 |
| 3603 if (instr->hydrogen()->from_inlined()) { | 3603 if (instr->hydrogen()->from_inlined()) { |
| 3604 __ subi(result, sp, Operand(2 * kPointerSize)); | 3604 __ subi(result, sp, Operand(2 * kPointerSize)); |
| (...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4523 } | 4523 } |
| 4524 } | 4524 } |
| 4525 | 4525 |
| 4526 | 4526 |
| 4527 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 4527 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 4528 DCHECK(ToRegister(instr->context()).is(cp)); | 4528 DCHECK(ToRegister(instr->context()).is(cp)); |
| 4529 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); | 4529 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); |
| 4530 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); | 4530 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); |
| 4531 | 4531 |
| 4532 __ mov(StoreDescriptor::NameRegister(), Operand(instr->name())); | 4532 __ mov(StoreDescriptor::NameRegister(), Operand(instr->name())); |
| 4533 Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->language_mode()); | 4533 Handle<Code> ic = |
| 4534 StoreIC::initialize_stub(isolate(), instr->language_mode(), |
| 4535 instr->hydrogen()->initialization_state()); |
| 4534 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4536 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 4535 } | 4537 } |
| 4536 | 4538 |
| 4537 | 4539 |
| 4538 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 4540 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
| 4539 Representation representation = instr->hydrogen()->length()->representation(); | 4541 Representation representation = instr->hydrogen()->length()->representation(); |
| 4540 DCHECK(representation.Equals(instr->hydrogen()->index()->representation())); | 4542 DCHECK(representation.Equals(instr->hydrogen()->index()->representation())); |
| 4541 DCHECK(representation.IsSmiOrInteger32()); | 4543 DCHECK(representation.IsSmiOrInteger32()); |
| 4542 | 4544 |
| 4543 Condition cc = instr->hydrogen()->allow_equality() ? lt : le; | 4545 Condition cc = instr->hydrogen()->allow_equality() ? lt : le; |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4787 } | 4789 } |
| 4788 } | 4790 } |
| 4789 | 4791 |
| 4790 | 4792 |
| 4791 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4793 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| 4792 DCHECK(ToRegister(instr->context()).is(cp)); | 4794 DCHECK(ToRegister(instr->context()).is(cp)); |
| 4793 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); | 4795 DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); |
| 4794 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); | 4796 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); |
| 4795 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); | 4797 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); |
| 4796 | 4798 |
| 4797 Handle<Code> ic = | 4799 Handle<Code> ic = CodeFactory::KeyedStoreICInOptimizedCode( |
| 4798 CodeFactory::KeyedStoreIC(isolate(), instr->language_mode()).code(); | 4800 isolate(), instr->language_mode(), |
| 4801 instr->hydrogen()->initialization_state()).code(); |
| 4799 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4802 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 4800 } | 4803 } |
| 4801 | 4804 |
| 4802 | 4805 |
| 4803 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 4806 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
| 4804 Register object_reg = ToRegister(instr->object()); | 4807 Register object_reg = ToRegister(instr->object()); |
| 4805 Register scratch = scratch0(); | 4808 Register scratch = scratch0(); |
| 4806 | 4809 |
| 4807 Handle<Map> from_map = instr->original_map(); | 4810 Handle<Map> from_map = instr->original_map(); |
| 4808 Handle<Map> to_map = instr->transitioned_map(); | 4811 Handle<Map> to_map = instr->transitioned_map(); |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5513 __ LoadP(ip, FieldMemOperand(ip, Cell::kValueOffset)); | 5516 __ LoadP(ip, FieldMemOperand(ip, Cell::kValueOffset)); |
| 5514 __ cmp(reg, ip); | 5517 __ cmp(reg, ip); |
| 5515 } else { | 5518 } else { |
| 5516 __ Cmpi(reg, Operand(object), r0); | 5519 __ Cmpi(reg, Operand(object), r0); |
| 5517 } | 5520 } |
| 5518 DeoptimizeIf(ne, instr, Deoptimizer::kValueMismatch); | 5521 DeoptimizeIf(ne, instr, Deoptimizer::kValueMismatch); |
| 5519 } | 5522 } |
| 5520 | 5523 |
| 5521 | 5524 |
| 5522 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { | 5525 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { |
| 5526 Register temp = ToRegister(instr->temp()); |
| 5523 { | 5527 { |
| 5524 PushSafepointRegistersScope scope(this); | 5528 PushSafepointRegistersScope scope(this); |
| 5525 __ push(object); | 5529 __ push(object); |
| 5526 __ li(cp, Operand::Zero()); | 5530 __ li(cp, Operand::Zero()); |
| 5527 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); | 5531 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); |
| 5528 RecordSafepointWithRegisters(instr->pointer_map(), 1, | 5532 RecordSafepointWithRegisters(instr->pointer_map(), 1, |
| 5529 Safepoint::kNoLazyDeopt); | 5533 Safepoint::kNoLazyDeopt); |
| 5530 __ StoreToSafepointRegisterSlot(r3, scratch0()); | 5534 __ StoreToSafepointRegisterSlot(r3, temp); |
| 5531 } | 5535 } |
| 5532 __ TestIfSmi(scratch0(), r0); | 5536 __ TestIfSmi(temp, r0); |
| 5533 DeoptimizeIf(eq, instr, Deoptimizer::kInstanceMigrationFailed, cr0); | 5537 DeoptimizeIf(eq, instr, Deoptimizer::kInstanceMigrationFailed, cr0); |
| 5534 } | 5538 } |
| 5535 | 5539 |
| 5536 | 5540 |
| 5537 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { | 5541 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { |
| 5538 class DeferredCheckMaps FINAL : public LDeferredCode { | 5542 class DeferredCheckMaps FINAL : public LDeferredCode { |
| 5539 public: | 5543 public: |
| 5540 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) | 5544 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) |
| 5541 : LDeferredCode(codegen), instr_(instr), object_(object) { | 5545 : LDeferredCode(codegen), instr_(instr), object_(object) { |
| 5542 SetExit(check_maps()); | 5546 SetExit(check_maps()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5554 }; | 5558 }; |
| 5555 | 5559 |
| 5556 if (instr->hydrogen()->IsStabilityCheck()) { | 5560 if (instr->hydrogen()->IsStabilityCheck()) { |
| 5557 const UniqueSet<Map>* maps = instr->hydrogen()->maps(); | 5561 const UniqueSet<Map>* maps = instr->hydrogen()->maps(); |
| 5558 for (int i = 0; i < maps->size(); ++i) { | 5562 for (int i = 0; i < maps->size(); ++i) { |
| 5559 AddStabilityDependency(maps->at(i).handle()); | 5563 AddStabilityDependency(maps->at(i).handle()); |
| 5560 } | 5564 } |
| 5561 return; | 5565 return; |
| 5562 } | 5566 } |
| 5563 | 5567 |
| 5564 Register map_reg = scratch0(); | 5568 Register object = ToRegister(instr->value()); |
| 5569 Register map_reg = ToRegister(instr->temp()); |
| 5565 | 5570 |
| 5566 LOperand* input = instr->value(); | 5571 __ LoadP(map_reg, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 5567 DCHECK(input->IsRegister()); | |
| 5568 Register reg = ToRegister(input); | |
| 5569 | |
| 5570 __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
| 5571 | 5572 |
| 5572 DeferredCheckMaps* deferred = NULL; | 5573 DeferredCheckMaps* deferred = NULL; |
| 5573 if (instr->hydrogen()->HasMigrationTarget()) { | 5574 if (instr->hydrogen()->HasMigrationTarget()) { |
| 5574 deferred = new (zone()) DeferredCheckMaps(this, instr, reg); | 5575 deferred = new (zone()) DeferredCheckMaps(this, instr, object); |
| 5575 __ bind(deferred->check_maps()); | 5576 __ bind(deferred->check_maps()); |
| 5576 } | 5577 } |
| 5577 | 5578 |
| 5578 const UniqueSet<Map>* maps = instr->hydrogen()->maps(); | 5579 const UniqueSet<Map>* maps = instr->hydrogen()->maps(); |
| 5579 Label success; | 5580 Label success; |
| 5580 for (int i = 0; i < maps->size() - 1; i++) { | 5581 for (int i = 0; i < maps->size() - 1; i++) { |
| 5581 Handle<Map> map = maps->at(i).handle(); | 5582 Handle<Map> map = maps->at(i).handle(); |
| 5582 __ CompareMap(map_reg, map, &success); | 5583 __ CompareMap(map_reg, map, &success); |
| 5583 __ beq(&success); | 5584 __ beq(&success); |
| 5584 } | 5585 } |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6243 __ Push(scope_info); | 6244 __ Push(scope_info); |
| 6244 __ push(ToRegister(instr->function())); | 6245 __ push(ToRegister(instr->function())); |
| 6245 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6246 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6246 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6247 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6247 } | 6248 } |
| 6248 | 6249 |
| 6249 | 6250 |
| 6250 #undef __ | 6251 #undef __ |
| 6251 } | 6252 } |
| 6252 } // namespace v8::internal | 6253 } // namespace v8::internal |
| OLD | NEW |