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 |