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 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/crankshaft/ia32/lithium-codegen-ia32.h" | 7 #include "src/crankshaft/ia32/lithium-codegen-ia32.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 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2137 if (expected.CanBeUndetectable()) { | 2137 if (expected.CanBeUndetectable()) { |
2138 // Undetectable -> false. | 2138 // Undetectable -> false. |
2139 __ test_b(FieldOperand(map, Map::kBitFieldOffset), | 2139 __ test_b(FieldOperand(map, Map::kBitFieldOffset), |
2140 1 << Map::kIsUndetectable); | 2140 1 << Map::kIsUndetectable); |
2141 __ j(not_zero, instr->FalseLabel(chunk_)); | 2141 __ j(not_zero, instr->FalseLabel(chunk_)); |
2142 } | 2142 } |
2143 } | 2143 } |
2144 | 2144 |
2145 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 2145 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |
2146 // spec object -> true. | 2146 // spec object -> true. |
2147 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); | 2147 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); |
2148 __ j(above_equal, instr->TrueLabel(chunk_)); | 2148 __ j(above_equal, instr->TrueLabel(chunk_)); |
2149 } | 2149 } |
2150 | 2150 |
2151 if (expected.Contains(ToBooleanStub::STRING)) { | 2151 if (expected.Contains(ToBooleanStub::STRING)) { |
2152 // String value -> false iff empty. | 2152 // String value -> false iff empty. |
2153 Label not_string; | 2153 Label not_string; |
2154 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); | 2154 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); |
2155 __ j(above_equal, ¬_string, Label::kNear); | 2155 __ j(above_equal, ¬_string, Label::kNear); |
2156 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 2156 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
2157 __ j(not_zero, instr->TrueLabel(chunk_)); | 2157 __ j(not_zero, instr->TrueLabel(chunk_)); |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2493 DCHECK(!input.is(temp)); | 2493 DCHECK(!input.is(temp)); |
2494 DCHECK(!input.is(temp2)); | 2494 DCHECK(!input.is(temp2)); |
2495 DCHECK(!temp.is(temp2)); | 2495 DCHECK(!temp.is(temp2)); |
2496 __ JumpIfSmi(input, is_false); | 2496 __ JumpIfSmi(input, is_false); |
2497 | 2497 |
2498 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { | 2498 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { |
2499 // Assuming the following assertions, we can use the same compares to test | 2499 // Assuming the following assertions, we can use the same compares to test |
2500 // for both being a function type and being in the object type range. | 2500 // for both being a function type and being in the object type range. |
2501 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 2501 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
2502 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2502 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
2503 FIRST_SPEC_OBJECT_TYPE + 1); | 2503 FIRST_JS_RECEIVER_TYPE + 1); |
2504 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2504 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
2505 LAST_SPEC_OBJECT_TYPE - 1); | 2505 LAST_JS_RECEIVER_TYPE - 1); |
2506 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 2506 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
2507 __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp); | 2507 __ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, temp); |
2508 __ j(below, is_false); | 2508 __ j(below, is_false); |
2509 __ j(equal, is_true); | 2509 __ j(equal, is_true); |
2510 __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE); | 2510 __ CmpInstanceType(temp, LAST_JS_RECEIVER_TYPE); |
2511 __ j(equal, is_true); | 2511 __ j(equal, is_true); |
2512 } else { | 2512 } else { |
2513 // Faster code path to avoid two compares: subtract lower bound from the | 2513 // Faster code path to avoid two compares: subtract lower bound from the |
2514 // actual type and do a signed compare with the width of the type range. | 2514 // actual type and do a signed compare with the width of the type range. |
2515 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); | 2515 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); |
2516 __ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); | 2516 __ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); |
2517 __ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2517 __ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
2518 __ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - | 2518 __ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - |
2519 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2519 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
2520 __ j(above, is_false); | 2520 __ j(above, is_false); |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3175 | 3175 |
3176 // Normal function. Replace undefined or null with global receiver. | 3176 // Normal function. Replace undefined or null with global receiver. |
3177 __ cmp(receiver, factory()->null_value()); | 3177 __ cmp(receiver, factory()->null_value()); |
3178 __ j(equal, &global_object, Label::kNear); | 3178 __ j(equal, &global_object, Label::kNear); |
3179 __ cmp(receiver, factory()->undefined_value()); | 3179 __ cmp(receiver, factory()->undefined_value()); |
3180 __ j(equal, &global_object, Label::kNear); | 3180 __ j(equal, &global_object, Label::kNear); |
3181 | 3181 |
3182 // The receiver should be a JS object. | 3182 // The receiver should be a JS object. |
3183 __ test(receiver, Immediate(kSmiTagMask)); | 3183 __ test(receiver, Immediate(kSmiTagMask)); |
3184 DeoptimizeIf(equal, instr, Deoptimizer::kSmi); | 3184 DeoptimizeIf(equal, instr, Deoptimizer::kSmi); |
3185 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch); | 3185 __ CmpObjectType(receiver, FIRST_JS_RECEIVER_TYPE, scratch); |
3186 DeoptimizeIf(below, instr, Deoptimizer::kNotAJavaScriptObject); | 3186 DeoptimizeIf(below, instr, Deoptimizer::kNotAJavaScriptObject); |
3187 | 3187 |
3188 __ jmp(&receiver_ok, Label::kNear); | 3188 __ jmp(&receiver_ok, Label::kNear); |
3189 __ bind(&global_object); | 3189 __ bind(&global_object); |
3190 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset)); | 3190 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset)); |
3191 __ mov(receiver, ContextOperand(receiver, Context::NATIVE_CONTEXT_INDEX)); | 3191 __ mov(receiver, ContextOperand(receiver, Context::NATIVE_CONTEXT_INDEX)); |
3192 __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_PROXY_INDEX)); | 3192 __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_PROXY_INDEX)); |
3193 __ bind(&receiver_ok); | 3193 __ bind(&receiver_ok); |
3194 } | 3194 } |
3195 | 3195 |
(...skipping 2068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5264 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 5264 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
5265 __ movzx_b(input, FieldOperand(input, Map::kBitFieldOffset)); | 5265 __ movzx_b(input, FieldOperand(input, Map::kBitFieldOffset)); |
5266 __ and_(input, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); | 5266 __ and_(input, (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); |
5267 __ cmp(input, 1 << Map::kIsCallable); | 5267 __ cmp(input, 1 << Map::kIsCallable); |
5268 final_branch_condition = equal; | 5268 final_branch_condition = equal; |
5269 | 5269 |
5270 } else if (String::Equals(type_name, factory()->object_string())) { | 5270 } else if (String::Equals(type_name, factory()->object_string())) { |
5271 __ JumpIfSmi(input, false_label, false_distance); | 5271 __ JumpIfSmi(input, false_label, false_distance); |
5272 __ cmp(input, factory()->null_value()); | 5272 __ cmp(input, factory()->null_value()); |
5273 __ j(equal, true_label, true_distance); | 5273 __ j(equal, true_label, true_distance); |
5274 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 5274 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
5275 __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, input); | 5275 __ CmpObjectType(input, FIRST_JS_RECEIVER_TYPE, input); |
5276 __ j(below, false_label, false_distance); | 5276 __ j(below, false_label, false_distance); |
5277 // Check for callable or undetectable objects => false. | 5277 // Check for callable or undetectable objects => false. |
5278 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 5278 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
5279 (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); | 5279 (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); |
5280 final_branch_condition = zero; | 5280 final_branch_condition = zero; |
5281 | 5281 |
5282 // clang-format off | 5282 // clang-format off |
5283 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | 5283 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ |
5284 } else if (String::Equals(type_name, factory()->type##_string())) { \ | 5284 } else if (String::Equals(type_name, factory()->type##_string())) { \ |
5285 __ JumpIfSmi(input, false_label, false_distance); \ | 5285 __ JumpIfSmi(input, false_label, false_distance); \ |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5444 | 5444 |
5445 GenerateOsrPrologue(); | 5445 GenerateOsrPrologue(); |
5446 } | 5446 } |
5447 | 5447 |
5448 | 5448 |
5449 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { | 5449 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
5450 DCHECK(ToRegister(instr->context()).is(esi)); | 5450 DCHECK(ToRegister(instr->context()).is(esi)); |
5451 __ test(eax, Immediate(kSmiTagMask)); | 5451 __ test(eax, Immediate(kSmiTagMask)); |
5452 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); | 5452 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); |
5453 | 5453 |
5454 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 5454 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); |
5455 __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); | 5455 __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); |
5456 DeoptimizeIf(below_equal, instr, Deoptimizer::kWrongInstanceType); | 5456 DeoptimizeIf(below_equal, instr, Deoptimizer::kWrongInstanceType); |
5457 | 5457 |
5458 Label use_cache, call_runtime; | 5458 Label use_cache, call_runtime; |
5459 __ CheckEnumCache(&call_runtime); | 5459 __ CheckEnumCache(&call_runtime); |
5460 | 5460 |
5461 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); | 5461 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); |
5462 __ jmp(&use_cache, Label::kNear); | 5462 __ jmp(&use_cache, Label::kNear); |
5463 | 5463 |
5464 // Get the set of properties to enumerate. | 5464 // Get the set of properties to enumerate. |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5588 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5588 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5589 } | 5589 } |
5590 | 5590 |
5591 | 5591 |
5592 #undef __ | 5592 #undef __ |
5593 | 5593 |
5594 } // namespace internal | 5594 } // namespace internal |
5595 } // namespace v8 | 5595 } // namespace v8 |
5596 | 5596 |
5597 #endif // V8_TARGET_ARCH_IA32 | 5597 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |