| 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 |