| 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-stubs.h" | 10 #include "src/code-stubs.h" |
| 11 #include "src/codegen.h" | 11 #include "src/codegen.h" |
| 12 #include "src/deoptimizer.h" | 12 #include "src/deoptimizer.h" |
| 13 #include "src/hydrogen-osr.h" | 13 #include "src/hydrogen-osr.h" |
| 14 #include "src/ia32/lithium-codegen-ia32.h" | 14 #include "src/ia32/lithium-codegen-ia32.h" |
| 15 #include "src/ic/stub-cache.h" |
| 15 | 16 |
| 16 namespace v8 { | 17 namespace v8 { |
| 17 namespace internal { | 18 namespace internal { |
| 18 | 19 |
| 19 // When invoking builtins, we need to record the safepoint in the middle of | 20 // When invoking builtins, we need to record the safepoint in the middle of |
| 20 // the invoke instruction sequence generated by the macro assembler. | 21 // the invoke instruction sequence generated by the macro assembler. |
| 21 class SafepointGenerator FINAL : public CallWrapper { | 22 class SafepointGenerator FINAL : public CallWrapper { |
| 22 public: | 23 public: |
| 23 SafepointGenerator(LCodeGen* codegen, | 24 SafepointGenerator(LCodeGen* codegen, |
| 24 LPointerMap* pointers, | 25 LPointerMap* pointers, |
| (...skipping 3115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3140 XMMRegister result = ToDoubleRegister(instr->result()); | 3141 XMMRegister result = ToDoubleRegister(instr->result()); |
| 3141 __ movsd(result, double_load_operand); | 3142 __ movsd(result, double_load_operand); |
| 3142 } | 3143 } |
| 3143 | 3144 |
| 3144 | 3145 |
| 3145 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3146 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3146 Register result = ToRegister(instr->result()); | 3147 Register result = ToRegister(instr->result()); |
| 3147 | 3148 |
| 3148 // Load the result. | 3149 // Load the result. |
| 3149 __ mov(result, | 3150 __ mov(result, |
| 3150 BuildFastArrayOperand(instr->elements(), | 3151 BuildFastArrayOperand(instr->elements(), instr->key(), |
| 3151 instr->key(), | |
| 3152 instr->hydrogen()->key()->representation(), | 3152 instr->hydrogen()->key()->representation(), |
| 3153 FAST_ELEMENTS, | 3153 FAST_ELEMENTS, instr->base_offset())); |
| 3154 instr->base_offset())); | |
| 3155 | 3154 |
| 3156 // Check for the hole value. | 3155 // Check for the hole value. |
| 3157 if (instr->hydrogen()->RequiresHoleCheck()) { | 3156 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3158 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3157 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
| 3159 __ test(result, Immediate(kSmiTagMask)); | 3158 __ test(result, Immediate(kSmiTagMask)); |
| 3160 DeoptimizeIf(not_equal, instr->environment()); | 3159 DeoptimizeIf(not_equal, instr->environment()); |
| 3161 } else { | 3160 } else { |
| 3162 __ cmp(result, factory()->the_hole_value()); | 3161 __ cmp(result, factory()->the_hole_value()); |
| 3163 DeoptimizeIf(equal, instr->environment()); | 3162 DeoptimizeIf(equal, instr->environment()); |
| 3164 } | 3163 } |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3440 LPointerMap* pointers = instr->pointer_map(); | 3439 LPointerMap* pointers = instr->pointer_map(); |
| 3441 SafepointGenerator generator( | 3440 SafepointGenerator generator( |
| 3442 this, pointers, Safepoint::kLazyDeopt); | 3441 this, pointers, Safepoint::kLazyDeopt); |
| 3443 ParameterCount count(arity); | 3442 ParameterCount count(arity); |
| 3444 ParameterCount expected(formal_parameter_count); | 3443 ParameterCount expected(formal_parameter_count); |
| 3445 __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator); | 3444 __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator); |
| 3446 } | 3445 } |
| 3447 } | 3446 } |
| 3448 | 3447 |
| 3449 | 3448 |
| 3449 void LCodeGen::DoTailCallThroughMegamorphicCache( |
| 3450 LTailCallThroughMegamorphicCache* instr) { |
| 3451 Register receiver = ToRegister(instr->receiver()); |
| 3452 Register name = ToRegister(instr->name()); |
| 3453 DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); |
| 3454 DCHECK(name.is(LoadDescriptor::NameRegister())); |
| 3455 |
| 3456 Register scratch = ebx; |
| 3457 Register extra = eax; |
| 3458 DCHECK(!scratch.is(receiver) && !scratch.is(name)); |
| 3459 DCHECK(!extra.is(receiver) && !extra.is(name)); |
| 3460 |
| 3461 // Important for the tail-call. |
| 3462 bool must_teardown_frame = NeedsEagerFrame(); |
| 3463 |
| 3464 // The probe will tail call to a handler if found. |
| 3465 isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), |
| 3466 must_teardown_frame, receiver, name, |
| 3467 scratch, extra); |
| 3468 |
| 3469 // Tail call to miss if we ended up here. |
| 3470 if (must_teardown_frame) __ leave(); |
| 3471 LoadIC::GenerateMiss(masm()); |
| 3472 } |
| 3473 |
| 3474 |
| 3450 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { | 3475 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { |
| 3451 DCHECK(ToRegister(instr->result()).is(eax)); | 3476 DCHECK(ToRegister(instr->result()).is(eax)); |
| 3452 | 3477 |
| 3453 LPointerMap* pointers = instr->pointer_map(); | 3478 LPointerMap* pointers = instr->pointer_map(); |
| 3454 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3479 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3455 | 3480 |
| 3456 if (instr->target()->IsConstantOperand()) { | 3481 if (instr->target()->IsConstantOperand()) { |
| 3457 LConstantOperand* target = LConstantOperand::cast(instr->target()); | 3482 LConstantOperand* target = LConstantOperand::cast(instr->target()); |
| 3458 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); | 3483 Handle<Code> code = Handle<Code>::cast(ToHandle(target)); |
| 3459 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); | 3484 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); |
| (...skipping 2210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5670 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5695 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5671 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5696 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5672 } | 5697 } |
| 5673 | 5698 |
| 5674 | 5699 |
| 5675 #undef __ | 5700 #undef __ |
| 5676 | 5701 |
| 5677 } } // namespace v8::internal | 5702 } } // namespace v8::internal |
| 5678 | 5703 |
| 5679 #endif // V8_TARGET_ARCH_IA32 | 5704 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |