| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2049 const intptr_t kNumTemps = 0; | 2049 const intptr_t kNumTemps = 0; |
| 2050 LocationSummary* locs = | 2050 LocationSummary* locs = |
| 2051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2052 locs->set_in(0, Location::RegisterLocation(A0)); | 2052 locs->set_in(0, Location::RegisterLocation(A0)); |
| 2053 locs->set_in(1, Location::RegisterLocation(A1)); | 2053 locs->set_in(1, Location::RegisterLocation(A1)); |
| 2054 locs->set_out(0, Location::RegisterLocation(V0)); | 2054 locs->set_out(0, Location::RegisterLocation(V0)); |
| 2055 return locs; | 2055 return locs; |
| 2056 } | 2056 } |
| 2057 | 2057 |
| 2058 | 2058 |
| 2059 // Inlines array allocation for known constant values. |
| 2060 static void InlineArrayAllocation(FlowGraphCompiler* compiler, |
| 2061 intptr_t num_elements, |
| 2062 Label* slow_path, |
| 2063 Label* done) { |
| 2064 const Register kLengthReg = A1; |
| 2065 const Register kElemTypeReg = A0; |
| 2066 const intptr_t kArraySize = Array::InstanceSize(num_elements); |
| 2067 |
| 2068 Isolate* isolate = Isolate::Current(); |
| 2069 Heap* heap = isolate->heap(); |
| 2070 |
| 2071 __ LoadImmediate(T3, heap->TopAddress()); |
| 2072 __ lw(V0, Address(T3, 0)); // Potential new object start. |
| 2073 // Potential next object start. |
| 2074 __ AddImmediateDetectOverflow(T1, V0, kArraySize, CMPRES1); |
| 2075 __ bltz(CMPRES1, slow_path); // CMPRES1 < 0 on overflow. |
| 2076 |
| 2077 // Check if the allocation fits into the remaining space. |
| 2078 // V0: potential new object start. |
| 2079 // T1: potential next object start. |
| 2080 __ LoadImmediate(T4, heap->EndAddress()); |
| 2081 __ lw(T4, Address(T4, 0)); |
| 2082 __ BranchUnsignedGreaterEqual(T1, T4, slow_path); |
| 2083 |
| 2084 |
| 2085 // Successfully allocated the object(s), now update top to point to |
| 2086 // next object start and initialize the object. |
| 2087 __ sw(T1, Address(T3, 0)); |
| 2088 __ addiu(V0, V0, Immediate(kHeapObjectTag)); |
| 2089 __ LoadImmediate(T2, kArraySize); |
| 2090 __ UpdateAllocationStatsWithSize(kArrayCid, T2, T4); |
| 2091 |
| 2092 // Initialize the tags. |
| 2093 // V0: new object start as a tagged pointer. |
| 2094 { |
| 2095 uword tags = 0; |
| 2096 tags = RawObject::ClassIdTag::update(kArrayCid, tags); |
| 2097 tags = RawObject::SizeTag::update(kArraySize, tags); |
| 2098 __ LoadImmediate(T2, tags); |
| 2099 __ sw(T2, FieldAddress(V0, Array::tags_offset())); // Store tags. |
| 2100 } |
| 2101 // V0: new object start as a tagged pointer. |
| 2102 // T1: new object end address. |
| 2103 |
| 2104 // Store the type argument field. |
| 2105 __ StoreIntoObjectNoBarrier(V0, |
| 2106 FieldAddress(V0, Array::type_arguments_offset()), |
| 2107 kElemTypeReg); |
| 2108 |
| 2109 // Set the length field. |
| 2110 __ StoreIntoObjectNoBarrier(V0, |
| 2111 FieldAddress(V0, Array::length_offset()), |
| 2112 kLengthReg); |
| 2113 |
| 2114 __ LoadImmediate(T7, reinterpret_cast<int32_t>(Object::null())); |
| 2115 // Initialize all array elements to raw_null. |
| 2116 // V0: new object start as a tagged pointer. |
| 2117 // T1: new object end address. |
| 2118 // T2: iterator which initially points to the start of the variable |
| 2119 // data area to be initialized. |
| 2120 // T7: null. |
| 2121 __ AddImmediate(T2, V0, sizeof(RawArray) - kHeapObjectTag); |
| 2122 |
| 2123 Label init_loop; |
| 2124 __ Bind(&init_loop); |
| 2125 __ BranchUnsignedGreaterEqual(T2, T1, done); |
| 2126 __ sw(T7, Address(T2, 0)); |
| 2127 __ b(&init_loop); |
| 2128 __ delay_slot()->addiu(T2, T2, Immediate(kWordSize)); |
| 2129 } |
| 2130 |
| 2131 |
| 2059 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2132 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2060 __ TraceSimMsg("CreateArrayInstr"); | 2133 __ TraceSimMsg("CreateArrayInstr"); |
| 2061 // Allocate the array. A1 = length, A0 = element type. | 2134 const Register kLengthReg = A1; |
| 2062 ASSERT(locs()->in(0).reg() == A0); | 2135 const Register kElemTypeReg = A0; |
| 2063 ASSERT(locs()->in(1).reg() == A1); | 2136 const Register kResultReg = V0; |
| 2137 ASSERT(locs()->in(0).reg() == kElemTypeReg); |
| 2138 ASSERT(locs()->in(1).reg() == kLengthReg); |
| 2139 |
| 2140 Label slow_path, done; |
| 2141 if (num_elements()->BindsToConstant() && |
| 2142 num_elements()->BoundConstant().IsSmi()) { |
| 2143 const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value(); |
| 2144 if ((length >= 0) && (length <= Array::kMaxElements)) { |
| 2145 Label slow_path, done; |
| 2146 InlineArrayAllocation(compiler, length, &slow_path, &done); |
| 2147 __ Bind(&slow_path); |
| 2148 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 2149 __ Push(kLengthReg); // length. |
| 2150 __ Push(kElemTypeReg); |
| 2151 compiler->GenerateRuntimeCall(token_pos(), |
| 2152 deopt_id(), |
| 2153 kAllocateArrayRuntimeEntry, |
| 2154 2, |
| 2155 locs()); |
| 2156 __ Drop(2); |
| 2157 __ Pop(kResultReg); |
| 2158 __ Bind(&done); |
| 2159 return; |
| 2160 } |
| 2161 } |
| 2162 |
| 2163 __ Bind(&slow_path); |
| 2064 compiler->GenerateCall(token_pos(), | 2164 compiler->GenerateCall(token_pos(), |
| 2065 &StubCode::AllocateArrayLabel(), | 2165 &StubCode::AllocateArrayLabel(), |
| 2066 PcDescriptors::kOther, | 2166 PcDescriptors::kOther, |
| 2067 locs()); | 2167 locs()); |
| 2068 ASSERT(locs()->out(0).reg() == V0); | 2168 __ Bind(&done); |
| 2169 ASSERT(locs()->out(0).reg() == kResultReg); |
| 2069 } | 2170 } |
| 2070 | 2171 |
| 2071 | 2172 |
| 2072 class BoxDoubleSlowPath : public SlowPathCode { | 2173 class BoxDoubleSlowPath : public SlowPathCode { |
| 2073 public: | 2174 public: |
| 2074 explicit BoxDoubleSlowPath(Instruction* instruction) | 2175 explicit BoxDoubleSlowPath(Instruction* instruction) |
| 2075 : instruction_(instruction) { } | 2176 : instruction_(instruction) { } |
| 2076 | 2177 |
| 2077 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2178 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2078 __ Comment("BoxDoubleSlowPath"); | 2179 __ Comment("BoxDoubleSlowPath"); |
| (...skipping 2470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4549 compiler->GenerateCall(token_pos(), | 4650 compiler->GenerateCall(token_pos(), |
| 4550 &label, | 4651 &label, |
| 4551 PcDescriptors::kOther, | 4652 PcDescriptors::kOther, |
| 4552 locs()); | 4653 locs()); |
| 4553 __ Drop(ArgumentCount()); // Discard arguments. | 4654 __ Drop(ArgumentCount()); // Discard arguments. |
| 4554 } | 4655 } |
| 4555 | 4656 |
| 4556 } // namespace dart | 4657 } // namespace dart |
| 4557 | 4658 |
| 4558 #endif // defined TARGET_ARCH_MIPS | 4659 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |