| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 | 49 |
| 50 // Intrinsify only for Smi value and index. Non-smi values need a store buffer | 50 // Intrinsify only for Smi value and index. Non-smi values need a store buffer |
| 51 // update. Array length is always a Smi. | 51 // update. Array length is always a Smi. |
| 52 void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) { | 52 void Intrinsifier::ObjectArraySetIndexed(Assembler* assembler) { |
| 53 Label fall_through; | 53 Label fall_through; |
| 54 | 54 |
| 55 if (Isolate::Current()->flags().type_checks()) { | 55 if (Isolate::Current()->flags().type_checks()) { |
| 56 const intptr_t type_args_field_offset = | 56 const intptr_t type_args_field_offset = |
| 57 ComputeObjectArrayTypeArgumentsOffset(); | 57 ComputeObjectArrayTypeArgumentsOffset(); |
| 58 // Inline simple tests (Smi, null), fallthrough if not positive. | 58 // Inline simple tests (Smi, null), fallthrough if not positive. |
| 59 const int32_t raw_null = reinterpret_cast<intptr_t>(Object::null()); | |
| 60 Label checked_ok; | 59 Label checked_ok; |
| 61 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value. | 60 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value. |
| 62 | 61 |
| 63 // Null value is valid for any type. | 62 // Null value is valid for any type. |
| 64 __ CompareImmediate(R2, raw_null); | 63 __ CompareObject(R2, Object::null_object()); |
| 65 __ b(&checked_ok, EQ); | 64 __ b(&checked_ok, EQ); |
| 66 | 65 |
| 67 __ ldr(R1, Address(SP, 2 * kWordSize)); // Array. | 66 __ ldr(R1, Address(SP, 2 * kWordSize)); // Array. |
| 68 __ ldr(R1, FieldAddress(R1, type_args_field_offset)); | 67 __ ldr(R1, FieldAddress(R1, type_args_field_offset)); |
| 69 | 68 |
| 70 // R1: Type arguments of array. | 69 // R1: Type arguments of array. |
| 71 __ CompareImmediate(R1, raw_null); | 70 __ CompareObject(R1, Object::null_object()); |
| 72 __ b(&checked_ok, EQ); | 71 __ b(&checked_ok, EQ); |
| 73 | 72 |
| 74 // Check if it's dynamic. | 73 // Check if it's dynamic. |
| 75 // Get type at index 0. | 74 // Get type at index 0. |
| 76 __ ldr(R0, FieldAddress(R1, TypeArguments::type_at_offset(0))); | 75 __ ldr(R0, FieldAddress(R1, TypeArguments::type_at_offset(0))); |
| 77 __ CompareObject(R0, Type::ZoneHandle(Type::DynamicType())); | 76 __ CompareObject(R0, Type::ZoneHandle(Type::DynamicType())); |
| 78 __ b(&checked_ok, EQ); | 77 __ b(&checked_ok, EQ); |
| 79 | 78 |
| 80 // Check for int and num. | 79 // Check for int and num. |
| 81 __ tst(R2, Operand(kSmiTagMask)); // Value is Smi? | 80 __ tst(R2, Operand(kSmiTagMask)); // Value is Smi? |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 __ b(&fall_through, EQ); // Must grow data. | 171 __ b(&fall_through, EQ); // Must grow data. |
| 173 const int32_t value_one = reinterpret_cast<int32_t>(Smi::New(1)); | 172 const int32_t value_one = reinterpret_cast<int32_t>(Smi::New(1)); |
| 174 // len = len + 1; | 173 // len = len + 1; |
| 175 __ add(R3, R1, Operand(value_one)); | 174 __ add(R3, R1, Operand(value_one)); |
| 176 __ StoreIntoSmiField(FieldAddress(R0, GrowableObjectArray::length_offset()), | 175 __ StoreIntoSmiField(FieldAddress(R0, GrowableObjectArray::length_offset()), |
| 177 R3); | 176 R3); |
| 178 __ ldr(R0, Address(SP, 0 * kWordSize)); // Value. | 177 __ ldr(R0, Address(SP, 0 * kWordSize)); // Value. |
| 179 ASSERT(kSmiTagShift == 1); | 178 ASSERT(kSmiTagShift == 1); |
| 180 __ add(R1, R2, Operand(R1, LSL, 1)); | 179 __ add(R1, R2, Operand(R1, LSL, 1)); |
| 181 __ StoreIntoObject(R2, FieldAddress(R1, Array::data_offset()), R0); | 180 __ StoreIntoObject(R2, FieldAddress(R1, Array::data_offset()), R0); |
| 182 const int32_t raw_null = reinterpret_cast<int32_t>(Object::null()); | 181 __ LoadObject(R0, Object::null_object()); |
| 183 __ LoadImmediate(R0, raw_null); | |
| 184 __ Ret(); | 182 __ Ret(); |
| 185 __ Bind(&fall_through); | 183 __ Bind(&fall_through); |
| 186 } | 184 } |
| 187 | 185 |
| 188 | 186 |
| 189 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \ | 187 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \ |
| 190 Label fall_through; \ | 188 Label fall_through; \ |
| 191 const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \ | 189 const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \ |
| 192 __ MaybeTraceAllocation(cid, R2, &fall_through, \ | 190 __ MaybeTraceAllocation(cid, R2, &fall_through, \ |
| 193 /* inline_isolate = */ false); \ | 191 /* inline_isolate = */ false); \ |
| (...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1580 static const intptr_t kSmiCidSource = kSmiCid << RawObject::kClassIdTagPos; | 1578 static const intptr_t kSmiCidSource = kSmiCid << RawObject::kClassIdTagPos; |
| 1581 __ ldr(R0, Address(SP, 0 * kWordSize)); | 1579 __ ldr(R0, Address(SP, 0 * kWordSize)); |
| 1582 | 1580 |
| 1583 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(&kSmiCidSource) + 1); | 1581 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(&kSmiCidSource) + 1); |
| 1584 __ tst(R0, Operand(kSmiTagMask)); | 1582 __ tst(R0, Operand(kSmiTagMask)); |
| 1585 __ mov(TMP, Operand(R0), NE); | 1583 __ mov(TMP, Operand(R0), NE); |
| 1586 __ LoadClassId(R1, TMP); | 1584 __ LoadClassId(R1, TMP); |
| 1587 __ LoadClassById(R2, R1); | 1585 __ LoadClassById(R2, R1); |
| 1588 // R2: class of instance (R0). | 1586 // R2: class of instance (R0). |
| 1589 __ ldr(R3, FieldAddress(R2, Class::signature_function_offset())); | 1587 __ ldr(R3, FieldAddress(R2, Class::signature_function_offset())); |
| 1590 __ CompareImmediate(R3, reinterpret_cast<int32_t>(Object::null())); | 1588 __ CompareObject(R3, Object::null_object()); |
| 1591 __ b(&fall_through, NE); | 1589 __ b(&fall_through, NE); |
| 1592 | 1590 |
| 1593 __ ldrh(R3, FieldAddress(R2, Class::num_type_arguments_offset())); | 1591 __ ldrh(R3, FieldAddress(R2, Class::num_type_arguments_offset())); |
| 1594 __ CompareImmediate(R3, 0); | 1592 __ CompareImmediate(R3, 0); |
| 1595 __ b(&fall_through, NE); | 1593 __ b(&fall_through, NE); |
| 1596 | 1594 |
| 1597 __ ldr(R0, FieldAddress(R2, Class::canonical_types_offset())); | 1595 __ ldr(R0, FieldAddress(R2, Class::canonical_types_offset())); |
| 1598 __ CompareImmediate(R0, reinterpret_cast<int32_t>(Object::null())); | 1596 __ CompareObject(R0, Object::null_object()); |
| 1599 __ b(&fall_through, EQ); | 1597 __ b(&fall_through, EQ); |
| 1600 __ Ret(); | 1598 __ Ret(); |
| 1601 | 1599 |
| 1602 __ Bind(&fall_through); | 1600 __ Bind(&fall_through); |
| 1603 } | 1601 } |
| 1604 | 1602 |
| 1605 | 1603 |
| 1606 void Intrinsifier::String_getHashCode(Assembler* assembler) { | 1604 void Intrinsifier::String_getHashCode(Assembler* assembler) { |
| 1607 __ ldr(R0, Address(SP, 0 * kWordSize)); | 1605 __ ldr(R0, Address(SP, 0 * kWordSize)); |
| 1608 __ ldr(R0, FieldAddress(R0, String::hash_offset())); | 1606 __ ldr(R0, FieldAddress(R0, String::hash_offset())); |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 | 2045 |
| 2048 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { | 2046 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { |
| 2049 __ LoadIsolate(R0); | 2047 __ LoadIsolate(R0); |
| 2050 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); | 2048 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); |
| 2051 __ Ret(); | 2049 __ Ret(); |
| 2052 } | 2050 } |
| 2053 | 2051 |
| 2054 } // namespace dart | 2052 } // namespace dart |
| 2055 | 2053 |
| 2056 #endif // defined TARGET_ARCH_ARM | 2054 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |