OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/crankshaft/x64/lithium-codegen-x64.h" | 7 #include "src/crankshaft/x64/lithium-codegen-x64.h" |
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 2175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 if (expected.CanBeUndetectable()) { | 2186 if (expected.CanBeUndetectable()) { |
2187 // Undetectable -> false. | 2187 // Undetectable -> false. |
2188 __ testb(FieldOperand(map, Map::kBitFieldOffset), | 2188 __ testb(FieldOperand(map, Map::kBitFieldOffset), |
2189 Immediate(1 << Map::kIsUndetectable)); | 2189 Immediate(1 << Map::kIsUndetectable)); |
2190 __ j(not_zero, instr->FalseLabel(chunk_)); | 2190 __ j(not_zero, instr->FalseLabel(chunk_)); |
2191 } | 2191 } |
2192 } | 2192 } |
2193 | 2193 |
2194 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 2194 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |
2195 // spec object -> true. | 2195 // spec object -> true. |
2196 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); | 2196 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); |
2197 __ j(above_equal, instr->TrueLabel(chunk_)); | 2197 __ j(above_equal, instr->TrueLabel(chunk_)); |
2198 } | 2198 } |
2199 | 2199 |
2200 if (expected.Contains(ToBooleanStub::STRING)) { | 2200 if (expected.Contains(ToBooleanStub::STRING)) { |
2201 // String value -> false iff empty. | 2201 // String value -> false iff empty. |
2202 Label not_string; | 2202 Label not_string; |
2203 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); | 2203 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); |
2204 __ j(above_equal, ¬_string, Label::kNear); | 2204 __ j(above_equal, ¬_string, Label::kNear); |
2205 __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 2205 __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
2206 __ j(not_zero, instr->TrueLabel(chunk_)); | 2206 __ j(not_zero, instr->TrueLabel(chunk_)); |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2550 DCHECK(!input.is(temp2)); | 2550 DCHECK(!input.is(temp2)); |
2551 DCHECK(!temp.is(temp2)); | 2551 DCHECK(!temp.is(temp2)); |
2552 | 2552 |
2553 __ JumpIfSmi(input, is_false); | 2553 __ JumpIfSmi(input, is_false); |
2554 | 2554 |
2555 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { | 2555 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { |
2556 // Assuming the following assertions, we can use the same compares to test | 2556 // Assuming the following assertions, we can use the same compares to test |
2557 // for both being a function type and being in the object type range. | 2557 // for both being a function type and being in the object type range. |
2558 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 2558 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
2559 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2559 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
2560 FIRST_SPEC_OBJECT_TYPE + 1); | 2560 FIRST_JS_RECEIVER_TYPE + 1); |
2561 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2561 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
2562 LAST_SPEC_OBJECT_TYPE - 1); | 2562 LAST_JS_RECEIVER_TYPE - 1); |
2563 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 2563 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
2564 __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp); | 2564 __ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, temp); |
2565 __ j(below, is_false); | 2565 __ j(below, is_false); |
2566 __ j(equal, is_true); | 2566 __ j(equal, is_true); |
2567 __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE); | 2567 __ CmpInstanceType(temp, LAST_JS_RECEIVER_TYPE); |
2568 __ j(equal, is_true); | 2568 __ j(equal, is_true); |
2569 } else { | 2569 } else { |
2570 // Faster code path to avoid two compares: subtract lower bound from the | 2570 // Faster code path to avoid two compares: subtract lower bound from the |
2571 // actual type and do a signed compare with the width of the type range. | 2571 // actual type and do a signed compare with the width of the type range. |
2572 __ movp(temp, FieldOperand(input, HeapObject::kMapOffset)); | 2572 __ movp(temp, FieldOperand(input, HeapObject::kMapOffset)); |
2573 __ movzxbl(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); | 2573 __ movzxbl(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); |
2574 __ subp(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2574 __ subp(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
2575 __ cmpp(temp2, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - | 2575 __ cmpp(temp2, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - |
2576 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2576 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
2577 __ j(above, is_false); | 2577 __ j(above, is_false); |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3253 | 3253 |
3254 // Normal function. Replace undefined or null with global receiver. | 3254 // Normal function. Replace undefined or null with global receiver. |
3255 __ CompareRoot(receiver, Heap::kNullValueRootIndex); | 3255 __ CompareRoot(receiver, Heap::kNullValueRootIndex); |
3256 __ j(equal, &global_object, Label::kNear); | 3256 __ j(equal, &global_object, Label::kNear); |
3257 __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex); | 3257 __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex); |
3258 __ j(equal, &global_object, Label::kNear); | 3258 __ j(equal, &global_object, Label::kNear); |
3259 | 3259 |
3260 // The receiver should be a JS object. | 3260 // The receiver should be a JS object. |
3261 Condition is_smi = __ CheckSmi(receiver); | 3261 Condition is_smi = __ CheckSmi(receiver); |
3262 DeoptimizeIf(is_smi, instr, Deoptimizer::kSmi); | 3262 DeoptimizeIf(is_smi, instr, Deoptimizer::kSmi); |
3263 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); | 3263 __ CmpObjectType(receiver, FIRST_JS_RECEIVER_TYPE, kScratchRegister); |
3264 DeoptimizeIf(below, instr, Deoptimizer::kNotAJavaScriptObject); | 3264 DeoptimizeIf(below, instr, Deoptimizer::kNotAJavaScriptObject); |
3265 | 3265 |
3266 __ jmp(&receiver_ok, Label::kNear); | 3266 __ jmp(&receiver_ok, Label::kNear); |
3267 __ bind(&global_object); | 3267 __ bind(&global_object); |
3268 __ movp(receiver, FieldOperand(function, JSFunction::kContextOffset)); | 3268 __ movp(receiver, FieldOperand(function, JSFunction::kContextOffset)); |
3269 __ movp(receiver, ContextOperand(receiver, Context::NATIVE_CONTEXT_INDEX)); | 3269 __ movp(receiver, ContextOperand(receiver, Context::NATIVE_CONTEXT_INDEX)); |
3270 __ movp(receiver, ContextOperand(receiver, Context::GLOBAL_PROXY_INDEX)); | 3270 __ movp(receiver, ContextOperand(receiver, Context::GLOBAL_PROXY_INDEX)); |
3271 | 3271 |
3272 __ bind(&receiver_ok); | 3272 __ bind(&receiver_ok); |
3273 } | 3273 } |
(...skipping 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5465 __ movzxbl(input, FieldOperand(input, Map::kBitFieldOffset)); | 5465 __ movzxbl(input, FieldOperand(input, Map::kBitFieldOffset)); |
5466 __ andb(input, | 5466 __ andb(input, |
5467 Immediate((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 5467 Immediate((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
5468 __ cmpb(input, Immediate(1 << Map::kIsCallable)); | 5468 __ cmpb(input, Immediate(1 << Map::kIsCallable)); |
5469 final_branch_condition = equal; | 5469 final_branch_condition = equal; |
5470 | 5470 |
5471 } else if (String::Equals(type_name, factory->object_string())) { | 5471 } else if (String::Equals(type_name, factory->object_string())) { |
5472 __ JumpIfSmi(input, false_label, false_distance); | 5472 __ JumpIfSmi(input, false_label, false_distance); |
5473 __ CompareRoot(input, Heap::kNullValueRootIndex); | 5473 __ CompareRoot(input, Heap::kNullValueRootIndex); |
5474 __ j(equal, true_label, true_distance); | 5474 __ j(equal, true_label, true_distance); |
5475 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 5475 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
5476 __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, input); | 5476 __ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, input); |
5477 __ j(below, false_label, false_distance); | 5477 __ j(below, false_label, false_distance); |
5478 // Check for callable or undetectable objects => false. | 5478 // Check for callable or undetectable objects => false. |
5479 __ testb(FieldOperand(input, Map::kBitFieldOffset), | 5479 __ testb(FieldOperand(input, Map::kBitFieldOffset), |
5480 Immediate((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 5480 Immediate((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
5481 final_branch_condition = zero; | 5481 final_branch_condition = zero; |
5482 | 5482 |
5483 // clang-format off | 5483 // clang-format off |
5484 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | 5484 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ |
5485 } else if (String::Equals(type_name, factory->type##_string())) { \ | 5485 } else if (String::Equals(type_name, factory->type##_string())) { \ |
5486 __ JumpIfSmi(input, false_label, false_distance); \ | 5486 __ JumpIfSmi(input, false_label, false_distance); \ |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5642 GenerateOsrPrologue(); | 5642 GenerateOsrPrologue(); |
5643 } | 5643 } |
5644 | 5644 |
5645 | 5645 |
5646 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { | 5646 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
5647 DCHECK(ToRegister(instr->context()).is(rsi)); | 5647 DCHECK(ToRegister(instr->context()).is(rsi)); |
5648 | 5648 |
5649 Condition cc = masm()->CheckSmi(rax); | 5649 Condition cc = masm()->CheckSmi(rax); |
5650 DeoptimizeIf(cc, instr, Deoptimizer::kSmi); | 5650 DeoptimizeIf(cc, instr, Deoptimizer::kSmi); |
5651 | 5651 |
5652 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 5652 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); |
5653 __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); | 5653 __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); |
5654 DeoptimizeIf(below_equal, instr, Deoptimizer::kWrongInstanceType); | 5654 DeoptimizeIf(below_equal, instr, Deoptimizer::kWrongInstanceType); |
5655 | 5655 |
5656 Label use_cache, call_runtime; | 5656 Label use_cache, call_runtime; |
5657 Register null_value = rdi; | 5657 Register null_value = rdi; |
5658 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 5658 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
5659 __ CheckEnumCache(null_value, &call_runtime); | 5659 __ CheckEnumCache(null_value, &call_runtime); |
5660 | 5660 |
5661 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); | 5661 __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); |
5662 __ jmp(&use_cache, Label::kNear); | 5662 __ jmp(&use_cache, Label::kNear); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5788 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5788 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5789 } | 5789 } |
5790 | 5790 |
5791 | 5791 |
5792 #undef __ | 5792 #undef __ |
5793 | 5793 |
5794 } // namespace internal | 5794 } // namespace internal |
5795 } // namespace v8 | 5795 } // namespace v8 |
5796 | 5796 |
5797 #endif // V8_TARGET_ARCH_X64 | 5797 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |