| 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/crankshaft/arm/lithium-codegen-arm.h" | 5 #include "src/crankshaft/arm/lithium-codegen-arm.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/crankshaft/arm/lithium-gap-resolver-arm.h" | 10 #include "src/crankshaft/arm/lithium-gap-resolver-arm.h" |
| (...skipping 2222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2233 if (expected.CanBeUndetectable()) { | 2233 if (expected.CanBeUndetectable()) { |
| 2234 // Undetectable -> false. | 2234 // Undetectable -> false. |
| 2235 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); | 2235 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 2236 __ tst(ip, Operand(1 << Map::kIsUndetectable)); | 2236 __ tst(ip, Operand(1 << Map::kIsUndetectable)); |
| 2237 __ b(ne, instr->FalseLabel(chunk_)); | 2237 __ b(ne, instr->FalseLabel(chunk_)); |
| 2238 } | 2238 } |
| 2239 } | 2239 } |
| 2240 | 2240 |
| 2241 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 2241 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |
| 2242 // spec object -> true. | 2242 // spec object -> true. |
| 2243 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); | 2243 __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); |
| 2244 __ b(ge, instr->TrueLabel(chunk_)); | 2244 __ b(ge, instr->TrueLabel(chunk_)); |
| 2245 } | 2245 } |
| 2246 | 2246 |
| 2247 if (expected.Contains(ToBooleanStub::STRING)) { | 2247 if (expected.Contains(ToBooleanStub::STRING)) { |
| 2248 // String value -> false iff empty. | 2248 // String value -> false iff empty. |
| 2249 Label not_string; | 2249 Label not_string; |
| 2250 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 2250 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
| 2251 __ b(ge, ¬_string); | 2251 __ b(ge, ¬_string); |
| 2252 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2252 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); |
| 2253 __ cmp(ip, Operand::Zero()); | 2253 __ cmp(ip, Operand::Zero()); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2590 DCHECK(!input.is(temp2)); | 2590 DCHECK(!input.is(temp2)); |
| 2591 DCHECK(!temp.is(temp2)); | 2591 DCHECK(!temp.is(temp2)); |
| 2592 | 2592 |
| 2593 __ JumpIfSmi(input, is_false); | 2593 __ JumpIfSmi(input, is_false); |
| 2594 | 2594 |
| 2595 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { | 2595 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { |
| 2596 // Assuming the following assertions, we can use the same compares to test | 2596 // Assuming the following assertions, we can use the same compares to test |
| 2597 // for both being a function type and being in the object type range. | 2597 // for both being a function type and being in the object type range. |
| 2598 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 2598 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
| 2599 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2599 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
| 2600 FIRST_SPEC_OBJECT_TYPE + 1); | 2600 FIRST_JS_RECEIVER_TYPE + 1); |
| 2601 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2601 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
| 2602 LAST_SPEC_OBJECT_TYPE - 1); | 2602 LAST_JS_RECEIVER_TYPE - 1); |
| 2603 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 2603 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 2604 __ CompareObjectType(input, temp, temp2, FIRST_SPEC_OBJECT_TYPE); | 2604 __ CompareObjectType(input, temp, temp2, FIRST_JS_RECEIVER_TYPE); |
| 2605 __ b(lt, is_false); | 2605 __ b(lt, is_false); |
| 2606 __ b(eq, is_true); | 2606 __ b(eq, is_true); |
| 2607 __ cmp(temp2, Operand(LAST_SPEC_OBJECT_TYPE)); | 2607 __ cmp(temp2, Operand(LAST_JS_RECEIVER_TYPE)); |
| 2608 __ b(eq, is_true); | 2608 __ b(eq, is_true); |
| 2609 } else { | 2609 } else { |
| 2610 // Faster code path to avoid two compares: subtract lower bound from the | 2610 // Faster code path to avoid two compares: subtract lower bound from the |
| 2611 // actual type and do a signed compare with the width of the type range. | 2611 // actual type and do a signed compare with the width of the type range. |
| 2612 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); | 2612 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 2613 __ ldrb(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset)); | 2613 __ ldrb(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset)); |
| 2614 __ sub(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2614 __ sub(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2615 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - | 2615 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - |
| 2616 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2616 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2617 __ b(gt, is_false); | 2617 __ b(gt, is_false); |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3279 __ LoadRoot(scratch, Heap::kNullValueRootIndex); | 3279 __ LoadRoot(scratch, Heap::kNullValueRootIndex); |
| 3280 __ cmp(receiver, scratch); | 3280 __ cmp(receiver, scratch); |
| 3281 __ b(eq, &global_object); | 3281 __ b(eq, &global_object); |
| 3282 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 3282 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
| 3283 __ cmp(receiver, scratch); | 3283 __ cmp(receiver, scratch); |
| 3284 __ b(eq, &global_object); | 3284 __ b(eq, &global_object); |
| 3285 | 3285 |
| 3286 // Deoptimize if the receiver is not a JS object. | 3286 // Deoptimize if the receiver is not a JS object. |
| 3287 __ SmiTst(receiver); | 3287 __ SmiTst(receiver); |
| 3288 DeoptimizeIf(eq, instr, Deoptimizer::kSmi); | 3288 DeoptimizeIf(eq, instr, Deoptimizer::kSmi); |
| 3289 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); | 3289 __ CompareObjectType(receiver, scratch, scratch, FIRST_JS_RECEIVER_TYPE); |
| 3290 DeoptimizeIf(lt, instr, Deoptimizer::kNotAJavaScriptObject); | 3290 DeoptimizeIf(lt, instr, Deoptimizer::kNotAJavaScriptObject); |
| 3291 | 3291 |
| 3292 __ b(&result_in_receiver); | 3292 __ b(&result_in_receiver); |
| 3293 __ bind(&global_object); | 3293 __ bind(&global_object); |
| 3294 __ ldr(result, FieldMemOperand(function, JSFunction::kContextOffset)); | 3294 __ ldr(result, FieldMemOperand(function, JSFunction::kContextOffset)); |
| 3295 __ ldr(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX)); | 3295 __ ldr(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX)); |
| 3296 __ ldr(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX)); | 3296 __ ldr(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX)); |
| 3297 | 3297 |
| 3298 if (result.is(receiver)) { | 3298 if (result.is(receiver)) { |
| 3299 __ bind(&result_in_receiver); | 3299 __ bind(&result_in_receiver); |
| (...skipping 2082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5382 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); | 5382 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); |
| 5383 __ and_(scratch, scratch, | 5383 __ and_(scratch, scratch, |
| 5384 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 5384 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
| 5385 __ cmp(scratch, Operand(1 << Map::kIsCallable)); | 5385 __ cmp(scratch, Operand(1 << Map::kIsCallable)); |
| 5386 final_branch_condition = eq; | 5386 final_branch_condition = eq; |
| 5387 | 5387 |
| 5388 } else if (String::Equals(type_name, factory->object_string())) { | 5388 } else if (String::Equals(type_name, factory->object_string())) { |
| 5389 __ JumpIfSmi(input, false_label); | 5389 __ JumpIfSmi(input, false_label); |
| 5390 __ CompareRoot(input, Heap::kNullValueRootIndex); | 5390 __ CompareRoot(input, Heap::kNullValueRootIndex); |
| 5391 __ b(eq, true_label); | 5391 __ b(eq, true_label); |
| 5392 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 5392 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 5393 __ CompareObjectType(input, scratch, ip, FIRST_SPEC_OBJECT_TYPE); | 5393 __ CompareObjectType(input, scratch, ip, FIRST_JS_RECEIVER_TYPE); |
| 5394 __ b(lt, false_label); | 5394 __ b(lt, false_label); |
| 5395 // Check for callable or undetectable objects => false. | 5395 // Check for callable or undetectable objects => false. |
| 5396 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); | 5396 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); |
| 5397 __ tst(scratch, | 5397 __ tst(scratch, |
| 5398 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 5398 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
| 5399 final_branch_condition = eq; | 5399 final_branch_condition = eq; |
| 5400 | 5400 |
| 5401 // clang-format off | 5401 // clang-format off |
| 5402 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | 5402 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ |
| 5403 } else if (String::Equals(type_name, factory->type##_string())) { \ | 5403 } else if (String::Equals(type_name, factory->type##_string())) { \ |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5566 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 5566 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
| 5567 | 5567 |
| 5568 GenerateOsrPrologue(); | 5568 GenerateOsrPrologue(); |
| 5569 } | 5569 } |
| 5570 | 5570 |
| 5571 | 5571 |
| 5572 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { | 5572 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
| 5573 __ SmiTst(r0); | 5573 __ SmiTst(r0); |
| 5574 DeoptimizeIf(eq, instr, Deoptimizer::kSmi); | 5574 DeoptimizeIf(eq, instr, Deoptimizer::kSmi); |
| 5575 | 5575 |
| 5576 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 5576 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); |
| 5577 __ CompareObjectType(r0, r1, r1, LAST_JS_PROXY_TYPE); | 5577 __ CompareObjectType(r0, r1, r1, LAST_JS_PROXY_TYPE); |
| 5578 DeoptimizeIf(le, instr, Deoptimizer::kWrongInstanceType); | 5578 DeoptimizeIf(le, instr, Deoptimizer::kWrongInstanceType); |
| 5579 | 5579 |
| 5580 Label use_cache, call_runtime; | 5580 Label use_cache, call_runtime; |
| 5581 Register null_value = r5; | 5581 Register null_value = r5; |
| 5582 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 5582 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
| 5583 __ CheckEnumCache(null_value, &call_runtime); | 5583 __ CheckEnumCache(null_value, &call_runtime); |
| 5584 | 5584 |
| 5585 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 5585 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 5586 __ b(&use_cache); | 5586 __ b(&use_cache); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5718 __ push(ToRegister(instr->function())); | 5718 __ push(ToRegister(instr->function())); |
| 5719 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5719 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5720 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5720 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5721 } | 5721 } |
| 5722 | 5722 |
| 5723 | 5723 |
| 5724 #undef __ | 5724 #undef __ |
| 5725 | 5725 |
| 5726 } // namespace internal | 5726 } // namespace internal |
| 5727 } // namespace v8 | 5727 } // namespace v8 |
| OLD | NEW |