| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 2040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2051 | 2051 |
| 2052 compiler->GenerateInstanceOf(token_pos(), | 2052 compiler->GenerateInstanceOf(token_pos(), |
| 2053 deopt_id(), | 2053 deopt_id(), |
| 2054 type(), | 2054 type(), |
| 2055 negate_result(), | 2055 negate_result(), |
| 2056 locs()); | 2056 locs()); |
| 2057 ASSERT(locs()->out(0).reg() == EAX); | 2057 ASSERT(locs()->out(0).reg() == EAX); |
| 2058 } | 2058 } |
| 2059 | 2059 |
| 2060 | 2060 |
| 2061 // TODO(srdjan): In case of constant inputs make CreateArray kNoCall and |
| 2062 // use slow path stub. |
| 2061 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { | 2063 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { |
| 2062 const intptr_t kNumInputs = 2; | 2064 const intptr_t kNumInputs = 2; |
| 2063 const intptr_t kNumTemps = 0; | 2065 const intptr_t kNumTemps = 0; |
| 2064 LocationSummary* locs = | 2066 LocationSummary* locs = |
| 2065 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2067 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2066 locs->set_in(0, Location::RegisterLocation(ECX)); | 2068 locs->set_in(0, Location::RegisterLocation(ECX)); |
| 2067 locs->set_in(1, Location::RegisterLocation(EDX)); | 2069 locs->set_in(1, Location::RegisterLocation(EDX)); |
| 2068 locs->set_out(0, Location::RegisterLocation(EAX)); | 2070 locs->set_out(0, Location::RegisterLocation(EAX)); |
| 2069 return locs; | 2071 return locs; |
| 2070 } | 2072 } |
| 2071 | 2073 |
| 2072 | 2074 |
| 2075 // Inlines array allocation for known constant values. |
| 2076 static void InlineArrayAllocation(FlowGraphCompiler* compiler, |
| 2077 intptr_t num_elements, |
| 2078 Label* slow_path, |
| 2079 Label* done) { |
| 2080 const Register kLengthReg = EDX; |
| 2081 const Register kElemTypeReg = ECX; |
| 2082 const intptr_t kArraySize = Array::InstanceSize(num_elements); |
| 2083 Isolate* isolate = Isolate::Current(); |
| 2084 Heap* heap = isolate->heap(); |
| 2085 |
| 2086 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| 2087 __ movl(EBX, EAX); |
| 2088 |
| 2089 __ addl(EBX, Immediate(kArraySize)); |
| 2090 __ j(CARRY, slow_path); |
| 2091 |
| 2092 // Check if the allocation fits into the remaining space. |
| 2093 // EAX: potential new object start. |
| 2094 // EBX: potential next object start. |
| 2095 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
| 2096 __ j(ABOVE_EQUAL, slow_path); |
| 2097 |
| 2098 // Successfully allocated the object(s), now update top to point to |
| 2099 // next object start and initialize the object. |
| 2100 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 2101 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 2102 __ UpdateAllocationStatsWithSize(kArrayCid, kArraySize, kNoRegister); |
| 2103 |
| 2104 // Initialize the tags. |
| 2105 // EAX: new object start as a tagged pointer. |
| 2106 { |
| 2107 uword tags = 0; |
| 2108 tags = RawObject::ClassIdTag::update(kArrayCid, tags); |
| 2109 tags = RawObject::SizeTag::update(kArraySize, tags); |
| 2110 __ movl(FieldAddress(EAX, Array::tags_offset()), Immediate(tags)); |
| 2111 } |
| 2112 |
| 2113 // Store the type argument field. |
| 2114 __ StoreIntoObjectNoBarrier(EAX, |
| 2115 FieldAddress(EAX, Array::type_arguments_offset()), |
| 2116 kElemTypeReg); |
| 2117 |
| 2118 // Set the length field. |
| 2119 __ StoreIntoObjectNoBarrier(EAX, |
| 2120 FieldAddress(EAX, Array::length_offset()), |
| 2121 kLengthReg); |
| 2122 |
| 2123 // Initialize all array elements to raw_null. |
| 2124 // EAX: new object start as a tagged pointer. |
| 2125 // EBX: new object end address. |
| 2126 // EDI: iterator which initially points to the start of the variable |
| 2127 // data area to be initialized. |
| 2128 const Immediate& raw_null = |
| 2129 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 2130 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); |
| 2131 Label init_loop; |
| 2132 __ Bind(&init_loop); |
| 2133 __ cmpl(EDI, EBX); |
| 2134 __ j(ABOVE_EQUAL, done, Assembler::kNearJump); |
| 2135 __ movl(Address(EDI, 0), raw_null); |
| 2136 __ addl(EDI, Immediate(kWordSize)); |
| 2137 __ jmp(&init_loop, Assembler::kNearJump); |
| 2138 } |
| 2139 |
| 2140 |
| 2073 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2141 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2074 // Allocate the array. EDX = length, ECX = element type. | 2142 // Allocate the array. EDX = length, ECX = element type. |
| 2075 ASSERT(locs()->in(0).reg() == ECX); | 2143 const Register kLengthReg = EDX; |
| 2076 ASSERT(locs()->in(1).reg() == EDX); | 2144 const Register kElemTypeReg = ECX; |
| 2145 const Register kResultReg = EAX; |
| 2146 ASSERT(locs()->in(0).reg() == kElemTypeReg); |
| 2147 ASSERT(locs()->in(1).reg() == kLengthReg); |
| 2148 |
| 2149 Label slow_path, done; |
| 2150 if (num_elements()->BindsToConstant() && |
| 2151 num_elements()->BoundConstant().IsSmi()) { |
| 2152 const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value(); |
| 2153 if ((length >= 0) && (length <= Array::kMaxElements)) { |
| 2154 Label slow_path, done; |
| 2155 InlineArrayAllocation(compiler, length, &slow_path, &done); |
| 2156 __ Bind(&slow_path); |
| 2157 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 2158 __ pushl(kLengthReg); |
| 2159 __ pushl(kElemTypeReg); |
| 2160 compiler->GenerateRuntimeCall(token_pos(), |
| 2161 deopt_id(), |
| 2162 kAllocateArrayRuntimeEntry, |
| 2163 2, |
| 2164 locs()); |
| 2165 __ Drop(2); |
| 2166 __ popl(kResultReg); |
| 2167 __ Bind(&done); |
| 2168 return; |
| 2169 } |
| 2170 } |
| 2171 |
| 2172 __ Bind(&slow_path); |
| 2077 compiler->GenerateCall(token_pos(), | 2173 compiler->GenerateCall(token_pos(), |
| 2078 &StubCode::AllocateArrayLabel(), | 2174 &StubCode::AllocateArrayLabel(), |
| 2079 PcDescriptors::kOther, | 2175 PcDescriptors::kOther, |
| 2080 locs()); | 2176 locs()); |
| 2081 ASSERT(locs()->out(0).reg() == EAX); | 2177 __ Bind(&done); |
| 2178 ASSERT(locs()->out(0).reg() == kResultReg); |
| 2082 } | 2179 } |
| 2083 | 2180 |
| 2084 | 2181 |
| 2085 class BoxDoubleSlowPath : public SlowPathCode { | 2182 class BoxDoubleSlowPath : public SlowPathCode { |
| 2086 public: | 2183 public: |
| 2087 explicit BoxDoubleSlowPath(Instruction* instruction) | 2184 explicit BoxDoubleSlowPath(Instruction* instruction) |
| 2088 : instruction_(instruction) { } | 2185 : instruction_(instruction) { } |
| 2089 | 2186 |
| 2090 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2187 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2091 __ Comment("BoxDoubleSlowPath"); | 2188 __ Comment("BoxDoubleSlowPath"); |
| (...skipping 4003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6095 PcDescriptors::kOther, | 6192 PcDescriptors::kOther, |
| 6096 locs()); | 6193 locs()); |
| 6097 __ Drop(ArgumentCount()); // Discard arguments. | 6194 __ Drop(ArgumentCount()); // Discard arguments. |
| 6098 } | 6195 } |
| 6099 | 6196 |
| 6100 } // namespace dart | 6197 } // namespace dart |
| 6101 | 6198 |
| 6102 #undef __ | 6199 #undef __ |
| 6103 | 6200 |
| 6104 #endif // defined TARGET_ARCH_IA32 | 6201 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |