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 #include "src/crankshaft/arm64/lithium-codegen-arm64.h" | 5 #include "src/crankshaft/arm64/lithium-codegen-arm64.h" |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1879 if (expected.CanBeUndetectable()) { | 1879 if (expected.CanBeUndetectable()) { |
1880 // Undetectable -> false. | 1880 // Undetectable -> false. |
1881 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 1881 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
1882 __ TestAndBranchIfAnySet( | 1882 __ TestAndBranchIfAnySet( |
1883 scratch, 1 << Map::kIsUndetectable, false_label); | 1883 scratch, 1 << Map::kIsUndetectable, false_label); |
1884 } | 1884 } |
1885 } | 1885 } |
1886 | 1886 |
1887 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 1887 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |
1888 // spec object -> true. | 1888 // spec object -> true. |
1889 __ CompareInstanceType(map, scratch, FIRST_SPEC_OBJECT_TYPE); | 1889 __ CompareInstanceType(map, scratch, FIRST_JS_RECEIVER_TYPE); |
1890 __ B(ge, true_label); | 1890 __ B(ge, true_label); |
1891 } | 1891 } |
1892 | 1892 |
1893 if (expected.Contains(ToBooleanStub::STRING)) { | 1893 if (expected.Contains(ToBooleanStub::STRING)) { |
1894 // String value -> false iff empty. | 1894 // String value -> false iff empty. |
1895 Label not_string; | 1895 Label not_string; |
1896 __ CompareInstanceType(map, scratch, FIRST_NONSTRING_TYPE); | 1896 __ CompareInstanceType(map, scratch, FIRST_NONSTRING_TYPE); |
1897 __ B(ge, ¬_string); | 1897 __ B(ge, ¬_string); |
1898 __ Ldr(scratch, FieldMemOperand(value, String::kLengthOffset)); | 1898 __ Ldr(scratch, FieldMemOperand(value, String::kLengthOffset)); |
1899 __ Cbz(scratch, false_label); | 1899 __ Cbz(scratch, false_label); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 Register scratch2 = ToRegister(instr->temp2()); | 2313 Register scratch2 = ToRegister(instr->temp2()); |
2314 | 2314 |
2315 __ JumpIfSmi(input, false_label); | 2315 __ JumpIfSmi(input, false_label); |
2316 | 2316 |
2317 Register map = scratch2; | 2317 Register map = scratch2; |
2318 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { | 2318 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { |
2319 // Assuming the following assertions, we can use the same compares to test | 2319 // Assuming the following assertions, we can use the same compares to test |
2320 // for both being a function type and being in the object type range. | 2320 // for both being a function type and being in the object type range. |
2321 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 2321 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
2322 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2322 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
2323 FIRST_SPEC_OBJECT_TYPE + 1); | 2323 FIRST_JS_RECEIVER_TYPE + 1); |
2324 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2324 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
2325 LAST_SPEC_OBJECT_TYPE - 1); | 2325 LAST_JS_RECEIVER_TYPE - 1); |
2326 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 2326 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
2327 | 2327 |
2328 // We expect CompareObjectType to load the object instance type in scratch1. | 2328 // We expect CompareObjectType to load the object instance type in scratch1. |
2329 __ CompareObjectType(input, map, scratch1, FIRST_SPEC_OBJECT_TYPE); | 2329 __ CompareObjectType(input, map, scratch1, FIRST_JS_RECEIVER_TYPE); |
2330 __ B(lt, false_label); | 2330 __ B(lt, false_label); |
2331 __ B(eq, true_label); | 2331 __ B(eq, true_label); |
2332 __ Cmp(scratch1, LAST_SPEC_OBJECT_TYPE); | 2332 __ Cmp(scratch1, LAST_JS_RECEIVER_TYPE); |
2333 __ B(eq, true_label); | 2333 __ B(eq, true_label); |
2334 } else { | 2334 } else { |
2335 __ IsObjectJSObjectType(input, map, scratch1, false_label); | 2335 __ IsObjectJSObjectType(input, map, scratch1, false_label); |
2336 } | 2336 } |
2337 | 2337 |
2338 // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. | 2338 // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. |
2339 // Check if the constructor in the map is a function. | 2339 // Check if the constructor in the map is a function. |
2340 { | 2340 { |
2341 UseScratchRegisterScope temps(masm()); | 2341 UseScratchRegisterScope temps(masm()); |
2342 Register instance_type = temps.AcquireX(); | 2342 Register instance_type = temps.AcquireX(); |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 | 2819 |
2820 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { | 2820 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
2821 Register object = ToRegister(instr->object()); | 2821 Register object = ToRegister(instr->object()); |
2822 Register null_value = x5; | 2822 Register null_value = x5; |
2823 | 2823 |
2824 DCHECK(instr->IsMarkedAsCall()); | 2824 DCHECK(instr->IsMarkedAsCall()); |
2825 DCHECK(object.Is(x0)); | 2825 DCHECK(object.Is(x0)); |
2826 | 2826 |
2827 DeoptimizeIfSmi(object, instr, Deoptimizer::kSmi); | 2827 DeoptimizeIfSmi(object, instr, Deoptimizer::kSmi); |
2828 | 2828 |
2829 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 2829 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); |
2830 __ CompareObjectType(object, x1, x1, LAST_JS_PROXY_TYPE); | 2830 __ CompareObjectType(object, x1, x1, LAST_JS_PROXY_TYPE); |
2831 DeoptimizeIf(le, instr, Deoptimizer::kNotAJavaScriptObject); | 2831 DeoptimizeIf(le, instr, Deoptimizer::kNotAJavaScriptObject); |
2832 | 2832 |
2833 Label use_cache, call_runtime; | 2833 Label use_cache, call_runtime; |
2834 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 2834 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
2835 __ CheckEnumCache(object, null_value, x1, x2, x3, x4, &call_runtime); | 2835 __ CheckEnumCache(object, null_value, x1, x2, x3, x4, &call_runtime); |
2836 | 2836 |
2837 __ Ldr(object, FieldMemOperand(object, HeapObject::kMapOffset)); | 2837 __ Ldr(object, FieldMemOperand(object, HeapObject::kMapOffset)); |
2838 __ B(&use_cache); | 2838 __ B(&use_cache); |
2839 | 2839 |
(...skipping 2872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5712 (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); | 5712 (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); |
5713 EmitCompareAndBranch(instr, eq, scratch, 1 << Map::kIsCallable); | 5713 EmitCompareAndBranch(instr, eq, scratch, 1 << Map::kIsCallable); |
5714 | 5714 |
5715 } else if (String::Equals(type_name, factory->object_string())) { | 5715 } else if (String::Equals(type_name, factory->object_string())) { |
5716 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); | 5716 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); |
5717 Register map = ToRegister(instr->temp1()); | 5717 Register map = ToRegister(instr->temp1()); |
5718 Register scratch = ToRegister(instr->temp2()); | 5718 Register scratch = ToRegister(instr->temp2()); |
5719 | 5719 |
5720 __ JumpIfSmi(value, false_label); | 5720 __ JumpIfSmi(value, false_label); |
5721 __ JumpIfRoot(value, Heap::kNullValueRootIndex, true_label); | 5721 __ JumpIfRoot(value, Heap::kNullValueRootIndex, true_label); |
5722 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 5722 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
5723 __ JumpIfObjectType(value, map, scratch, FIRST_SPEC_OBJECT_TYPE, | 5723 __ JumpIfObjectType(value, map, scratch, FIRST_JS_RECEIVER_TYPE, |
5724 false_label, lt); | 5724 false_label, lt); |
5725 // Check for callable or undetectable objects => false. | 5725 // Check for callable or undetectable objects => false. |
5726 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 5726 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
5727 EmitTestAndBranch(instr, eq, scratch, | 5727 EmitTestAndBranch(instr, eq, scratch, |
5728 (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); | 5728 (1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)); |
5729 | 5729 |
5730 // clang-format off | 5730 // clang-format off |
5731 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | 5731 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ |
5732 } else if (String::Equals(type_name, factory->type##_string())) { \ | 5732 } else if (String::Equals(type_name, factory->type##_string())) { \ |
5733 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); \ | 5733 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); \ |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5786 // Do not transform the receiver to object for builtins. | 5786 // Do not transform the receiver to object for builtins. |
5787 __ Tbnz(result, SharedFunctionInfo::kNative, ©_receiver); | 5787 __ Tbnz(result, SharedFunctionInfo::kNative, ©_receiver); |
5788 } | 5788 } |
5789 | 5789 |
5790 // Normal function. Replace undefined or null with global receiver. | 5790 // Normal function. Replace undefined or null with global receiver. |
5791 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &global_object); | 5791 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &global_object); |
5792 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object); | 5792 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object); |
5793 | 5793 |
5794 // Deoptimize if the receiver is not a JS object. | 5794 // Deoptimize if the receiver is not a JS object. |
5795 DeoptimizeIfSmi(receiver, instr, Deoptimizer::kSmi); | 5795 DeoptimizeIfSmi(receiver, instr, Deoptimizer::kSmi); |
5796 __ CompareObjectType(receiver, result, result, FIRST_SPEC_OBJECT_TYPE); | 5796 __ CompareObjectType(receiver, result, result, FIRST_JS_RECEIVER_TYPE); |
5797 __ B(ge, ©_receiver); | 5797 __ B(ge, ©_receiver); |
5798 Deoptimize(instr, Deoptimizer::kNotAJavaScriptObject); | 5798 Deoptimize(instr, Deoptimizer::kNotAJavaScriptObject); |
5799 | 5799 |
5800 __ Bind(&global_object); | 5800 __ Bind(&global_object); |
5801 __ Ldr(result, FieldMemOperand(function, JSFunction::kContextOffset)); | 5801 __ Ldr(result, FieldMemOperand(function, JSFunction::kContextOffset)); |
5802 __ Ldr(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX)); | 5802 __ Ldr(result, ContextMemOperand(result, Context::NATIVE_CONTEXT_INDEX)); |
5803 __ Ldr(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX)); | 5803 __ Ldr(result, ContextMemOperand(result, Context::GLOBAL_PROXY_INDEX)); |
5804 __ B(&done); | 5804 __ B(&done); |
5805 | 5805 |
5806 __ Bind(©_receiver); | 5806 __ Bind(©_receiver); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5895 Handle<ScopeInfo> scope_info = instr->scope_info(); | 5895 Handle<ScopeInfo> scope_info = instr->scope_info(); |
5896 __ Push(scope_info); | 5896 __ Push(scope_info); |
5897 __ Push(ToRegister(instr->function())); | 5897 __ Push(ToRegister(instr->function())); |
5898 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5898 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5899 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5899 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5900 } | 5900 } |
5901 | 5901 |
5902 | 5902 |
5903 } // namespace internal | 5903 } // namespace internal |
5904 } // namespace v8 | 5904 } // namespace v8 |
OLD | NEW |