Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: runtime/vm/intermediate_language_mips.cc

Issue 282073006: Inline Array allocation for constant lengths (except ARM64). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698