| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 2813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2824 __ cmp(result, factory()->the_hole_value()); | 2824 __ cmp(result, factory()->the_hole_value()); |
| 2825 DeoptimizeIf(equal, instr, "hole"); | 2825 DeoptimizeIf(equal, instr, "hole"); |
| 2826 } | 2826 } |
| 2827 } | 2827 } |
| 2828 | 2828 |
| 2829 | 2829 |
| 2830 template <class T> | 2830 template <class T> |
| 2831 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2831 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
| 2832 DCHECK(FLAG_vector_ics); | 2832 DCHECK(FLAG_vector_ics); |
| 2833 Register vector_register = ToRegister(instr->temp_vector()); | 2833 Register vector_register = ToRegister(instr->temp_vector()); |
| 2834 Register slot_register = VectorLoadICDescriptor::SlotRegister(); |
| 2834 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); | 2835 DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister())); |
| 2836 DCHECK(slot_register.is(eax)); |
| 2837 |
| 2838 AllowDeferredHandleDereference vector_structure_check; |
| 2835 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); | 2839 Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector(); |
| 2836 __ mov(vector_register, vector); | 2840 __ mov(vector_register, vector); |
| 2837 // No need to allocate this register. | 2841 // No need to allocate this register. |
| 2838 DCHECK(VectorLoadICDescriptor::SlotRegister().is(eax)); | 2842 FeedbackVectorICSlot slot = instr->hydrogen()->slot(); |
| 2839 int index = vector->GetIndex(instr->hydrogen()->slot()); | 2843 int index = vector->GetIndex(slot); |
| 2840 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2844 __ mov(slot_register, Immediate(Smi::FromInt(index))); |
| 2841 Immediate(Smi::FromInt(index))); | |
| 2842 } | 2845 } |
| 2843 | 2846 |
| 2844 | 2847 |
| 2845 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2848 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 2846 DCHECK(ToRegister(instr->context()).is(esi)); | 2849 DCHECK(ToRegister(instr->context()).is(esi)); |
| 2847 DCHECK(ToRegister(instr->global_object()) | 2850 DCHECK(ToRegister(instr->global_object()) |
| 2848 .is(LoadDescriptor::ReceiverRegister())); | 2851 .is(LoadDescriptor::ReceiverRegister())); |
| 2849 DCHECK(ToRegister(instr->result()).is(eax)); | 2852 DCHECK(ToRegister(instr->result()).is(eax)); |
| 2850 | 2853 |
| 2851 __ mov(LoadDescriptor::NameRegister(), instr->name()); | 2854 __ mov(LoadDescriptor::NameRegister(), instr->name()); |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3445 } | 3448 } |
| 3446 } | 3449 } |
| 3447 | 3450 |
| 3448 | 3451 |
| 3449 void LCodeGen::DoTailCallThroughMegamorphicCache( | 3452 void LCodeGen::DoTailCallThroughMegamorphicCache( |
| 3450 LTailCallThroughMegamorphicCache* instr) { | 3453 LTailCallThroughMegamorphicCache* instr) { |
| 3451 Register receiver = ToRegister(instr->receiver()); | 3454 Register receiver = ToRegister(instr->receiver()); |
| 3452 Register name = ToRegister(instr->name()); | 3455 Register name = ToRegister(instr->name()); |
| 3453 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); | 3456 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |
| 3454 DCHECK(name.is(LoadDescriptor::NameRegister())); | 3457 DCHECK(name.is(LoadDescriptor::NameRegister())); |
| 3458 Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg; |
| 3459 Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg; |
| 3455 | 3460 |
| 3456 Register scratch = ebx; | 3461 Register scratch = ebx; |
| 3457 Register extra = eax; | 3462 Register extra = edi; |
| 3463 DCHECK(!extra.is(slot) && !extra.is(vector)); |
| 3458 DCHECK(!scratch.is(receiver) && !scratch.is(name)); | 3464 DCHECK(!scratch.is(receiver) && !scratch.is(name)); |
| 3459 DCHECK(!extra.is(receiver) && !extra.is(name)); | 3465 DCHECK(!extra.is(receiver) && !extra.is(name)); |
| 3460 | 3466 |
| 3461 // Important for the tail-call. | 3467 // Important for the tail-call. |
| 3462 bool must_teardown_frame = NeedsEagerFrame(); | 3468 bool must_teardown_frame = NeedsEagerFrame(); |
| 3463 | 3469 |
| 3464 // The probe will tail call to a handler if found. | 3470 if (!instr->hydrogen()->is_just_miss()) { |
| 3465 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), | 3471 if (FLAG_vector_ics) { |
| 3466 must_teardown_frame, receiver, name, | 3472 __ push(slot); |
| 3467 scratch, extra); | 3473 __ push(vector); |
| 3474 } |
| 3475 |
| 3476 // The probe will tail call to a handler if found. |
| 3477 // If --vector-ics is on, then it knows to pop the two args first. |
| 3478 DCHECK(!instr->hydrogen()->is_keyed_load()); |
| 3479 isolate()->stub_cache()->GenerateProbe( |
| 3480 masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame, |
| 3481 receiver, name, scratch, extra); |
| 3482 |
| 3483 if (FLAG_vector_ics) { |
| 3484 __ pop(vector); |
| 3485 __ pop(slot); |
| 3486 } |
| 3487 } |
| 3468 | 3488 |
| 3469 // Tail call to miss if we ended up here. | 3489 // Tail call to miss if we ended up here. |
| 3470 if (must_teardown_frame) __ leave(); | 3490 if (must_teardown_frame) __ leave(); |
| 3471 LoadIC::GenerateMiss(masm()); | 3491 if (instr->hydrogen()->is_keyed_load()) { |
| 3492 KeyedLoadIC::GenerateMiss(masm()); |
| 3493 } else { |
| 3494 LoadIC::GenerateMiss(masm()); |
| 3495 } |
| 3472 } | 3496 } |
| 3473 | 3497 |
| 3474 | 3498 |
| 3475 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 3499 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 3476 DCHECK(ToRegister(instr->result()).is(eax)); | 3500 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3477 | 3501 |
| 3478 LPointerMap* pointers = instr->pointer_map(); | 3502 if (instr->hydrogen()->IsTailCall()) { |
| 3479 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3503 if (NeedsEagerFrame()) __ leave(); |
| 3480 | 3504 |
| 3481 if (instr->target()->IsConstantOperand()) { | 3505 if (instr->target()->IsConstantOperand()) { |
| 3482 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 3506 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 3483 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 3507 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 3484 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); | 3508 __ jmp(code, RelocInfo::CODE_TARGET); |
| 3485 __ call(code, RelocInfo::CODE_TARGET); | 3509 } else { |
| 3510 DCHECK(instr->target()->IsRegister()); |
| 3511 Register target = ToRegister(instr->target()); |
| 3512 __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 3513 __ jmp(target); |
| 3514 } |
| 3486 } else { | 3515 } else { |
| 3487 DCHECK(instr->target()->IsRegister()); | 3516 LPointerMap* pointers = instr->pointer_map(); |
| 3488 Register target = ToRegister(instr->target()); | 3517 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3489 generator.BeforeCall(__ CallSize(Operand(target))); | 3518 |
| 3490 __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 3519 if (instr->target()->IsConstantOperand()) { |
| 3491 __ call(target); | 3520 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 3521 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 3522 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); |
| 3523 __ call(code, RelocInfo::CODE_TARGET); |
| 3524 } else { |
| 3525 DCHECK(instr->target()->IsRegister()); |
| 3526 Register target = ToRegister(instr->target()); |
| 3527 generator.BeforeCall(__ CallSize(Operand(target))); |
| 3528 __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 3529 __ call(target); |
| 3530 } |
| 3531 generator.AfterCall(); |
| 3492 } | 3532 } |
| 3493 generator.AfterCall(); | |
| 3494 } | 3533 } |
| 3495 | 3534 |
| 3496 | 3535 |
| 3497 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 3536 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |
| 3498 DCHECK(ToRegister(instr->function()).is(edi)); | 3537 DCHECK(ToRegister(instr->function()).is(edi)); |
| 3499 DCHECK(ToRegister(instr->result()).is(eax)); | 3538 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3500 | 3539 |
| 3501 if (instr->hydrogen()->pass_argument_count()) { | 3540 if (instr->hydrogen()->pass_argument_count()) { |
| 3502 __ mov(eax, instr->arity()); | 3541 __ mov(eax, instr->arity()); |
| 3503 } | 3542 } |
| (...skipping 2199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5703 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5742 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5704 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5743 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5705 } | 5744 } |
| 5706 | 5745 |
| 5707 | 5746 |
| 5708 #undef __ | 5747 #undef __ |
| 5709 | 5748 |
| 5710 } } // namespace v8::internal | 5749 } } // namespace v8::internal |
| 5711 | 5750 |
| 5712 #endif // V8_TARGET_ARCH_IA32 | 5751 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |