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 |