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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 break; | 204 break; |
205 default: | 205 default: |
206 UNREACHABLE(); | 206 UNREACHABLE(); |
207 } | 207 } |
208 } | 208 } |
209 } | 209 } |
210 | 210 |
211 | 211 |
212 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, | 212 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, |
213 bool opt) const { | 213 bool opt) const { |
214 const intptr_t kNumInputs = 2; | 214 const intptr_t kNumInputs = 3; |
215 const intptr_t kNumTemps = 0; | 215 const intptr_t kNumTemps = 0; |
216 LocationSummary* summary = new (zone) | 216 LocationSummary* summary = new (zone) |
217 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 217 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
218 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. | 218 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. |
219 summary->set_in(1, Location::RegisterLocation(EDX)); // Type arguments. | 219 summary->set_in(1, Location::RegisterLocation(EDX)); // Instant. type args. |
| 220 summary->set_in(2, Location::RegisterLocation(ECX)); // Function type args. |
220 summary->set_out(0, Location::RegisterLocation(EAX)); | 221 summary->set_out(0, Location::RegisterLocation(EAX)); |
221 return summary; | 222 return summary; |
222 } | 223 } |
223 | 224 |
224 | 225 |
225 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, | 226 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, |
226 bool opt) const { | 227 bool opt) const { |
227 const intptr_t kNumInputs = 1; | 228 const intptr_t kNumInputs = 1; |
228 const intptr_t kNumTemps = 0; | 229 const intptr_t kNumTemps = 0; |
229 LocationSummary* locs = new (zone) | 230 LocationSummary* locs = new (zone) |
(...skipping 1761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1991 value, CanValueBeSmi()); | 1992 value, CanValueBeSmi()); |
1992 } else { | 1993 } else { |
1993 __ StoreIntoObjectNoBarrier( | 1994 __ StoreIntoObjectNoBarrier( |
1994 temp, FieldAddress(temp, Field::static_value_offset()), value); | 1995 temp, FieldAddress(temp, Field::static_value_offset()), value); |
1995 } | 1996 } |
1996 } | 1997 } |
1997 | 1998 |
1998 | 1999 |
1999 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, | 2000 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, |
2000 bool opt) const { | 2001 bool opt) const { |
2001 const intptr_t kNumInputs = 2; | 2002 const intptr_t kNumInputs = 3; |
2002 const intptr_t kNumTemps = 0; | 2003 const intptr_t kNumTemps = 0; |
2003 LocationSummary* summary = new (zone) | 2004 LocationSummary* summary = new (zone) |
2004 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2005 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2005 summary->set_in(0, Location::RegisterLocation(EAX)); | 2006 summary->set_in(0, Location::RegisterLocation(EAX)); // Instance. |
2006 summary->set_in(1, Location::RegisterLocation(EDX)); | 2007 summary->set_in(1, Location::RegisterLocation(EDX)); // Instant. type args. |
| 2008 summary->set_in(2, Location::RegisterLocation(ECX)); // Function type args. |
2007 summary->set_out(0, Location::RegisterLocation(EAX)); | 2009 summary->set_out(0, Location::RegisterLocation(EAX)); |
2008 return summary; | 2010 return summary; |
2009 } | 2011 } |
2010 | 2012 |
2011 | 2013 |
2012 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2014 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2013 ASSERT(locs()->in(0).reg() == EAX); // Value. | 2015 ASSERT(locs()->in(0).reg() == EAX); // Value. |
2014 ASSERT(locs()->in(1).reg() == EDX); // Instantiator type arguments. | 2016 ASSERT(locs()->in(1).reg() == EDX); // Instantiator type arguments. |
| 2017 ASSERT(locs()->in(2).reg() == ECX); // Function type arguments. |
2015 | 2018 |
2016 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); | 2019 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); |
2017 ASSERT(locs()->out(0).reg() == EAX); | 2020 ASSERT(locs()->out(0).reg() == EAX); |
2018 } | 2021 } |
2019 | 2022 |
2020 | 2023 |
2021 // TODO(srdjan): In case of constant inputs make CreateArray kNoCall and | 2024 // TODO(srdjan): In case of constant inputs make CreateArray kNoCall and |
2022 // use slow path stub. | 2025 // use slow path stub. |
2023 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, | 2026 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, |
2024 bool opt) const { | 2027 bool opt) const { |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2249 | 2252 |
2250 __ Bind(&load_pointer); | 2253 __ Bind(&load_pointer); |
2251 } | 2254 } |
2252 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); | 2255 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); |
2253 __ Bind(&done); | 2256 __ Bind(&done); |
2254 } | 2257 } |
2255 | 2258 |
2256 | 2259 |
2257 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, | 2260 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, |
2258 bool opt) const { | 2261 bool opt) const { |
2259 const intptr_t kNumInputs = 1; | 2262 const intptr_t kNumInputs = 2; |
2260 const intptr_t kNumTemps = 0; | 2263 const intptr_t kNumTemps = 0; |
2261 LocationSummary* locs = new (zone) | 2264 LocationSummary* locs = new (zone) |
2262 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2265 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2263 locs->set_in(0, Location::RegisterLocation(EAX)); | 2266 locs->set_in(0, Location::RegisterLocation(EAX)); // Instant. type args. |
| 2267 locs->set_in(1, Location::RegisterLocation(EDX)); // Function type args. |
2264 locs->set_out(0, Location::RegisterLocation(EAX)); | 2268 locs->set_out(0, Location::RegisterLocation(EAX)); |
2265 return locs; | 2269 return locs; |
2266 } | 2270 } |
2267 | 2271 |
2268 | 2272 |
2269 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2273 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2270 Register instantiator_reg = locs()->in(0).reg(); | 2274 Register instantiator_type_args_reg = locs()->in(0).reg(); |
| 2275 Register function_type_args_reg = locs()->in(1).reg(); |
2271 Register result_reg = locs()->out(0).reg(); | 2276 Register result_reg = locs()->out(0).reg(); |
2272 | 2277 |
2273 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2278 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
| 2279 // 'function_type_args_reg' is a TypeArguments object (or null). |
2274 // A runtime call to instantiate the type is required. | 2280 // A runtime call to instantiate the type is required. |
2275 __ PushObject(Object::null_object()); // Make room for the result. | 2281 __ PushObject(Object::null_object()); // Make room for the result. |
2276 __ PushObject(type()); | 2282 __ PushObject(type()); |
2277 __ pushl(instantiator_reg); // Push instantiator type arguments. | 2283 __ pushl(instantiator_type_args_reg); // Push instantiator type arguments. |
| 2284 __ pushl(function_type_args_reg); // Push function type arguments. |
2278 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2285 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2279 kInstantiateTypeRuntimeEntry, 2, locs()); | 2286 kInstantiateTypeRuntimeEntry, 3, locs()); |
2280 __ Drop(2); // Drop instantiator and uninstantiated type. | 2287 __ Drop(3); // Drop 2 type argument vectors and uninstantiated type. |
2281 __ popl(result_reg); // Pop instantiated type. | 2288 __ popl(result_reg); // Pop instantiated type. |
2282 ASSERT(instantiator_reg == result_reg); | 2289 ASSERT(instantiator_type_args_reg == result_reg); |
2283 } | 2290 } |
2284 | 2291 |
2285 | 2292 |
2286 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( | 2293 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
2287 Zone* zone, | 2294 Zone* zone, |
2288 bool opt) const { | 2295 bool opt) const { |
2289 const intptr_t kNumInputs = 1; | 2296 const intptr_t kNumInputs = 2; |
2290 const intptr_t kNumTemps = 0; | 2297 const intptr_t kNumTemps = 0; |
2291 LocationSummary* locs = new (zone) | 2298 LocationSummary* locs = new (zone) |
2292 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2299 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2293 locs->set_in(0, Location::RegisterLocation(EAX)); | 2300 locs->set_in(0, Location::RegisterLocation(EAX)); // Instant. type args. |
| 2301 locs->set_in(1, Location::RegisterLocation(ECX)); // Function type args. |
2294 locs->set_out(0, Location::RegisterLocation(EAX)); | 2302 locs->set_out(0, Location::RegisterLocation(EAX)); |
2295 return locs; | 2303 return locs; |
2296 } | 2304 } |
2297 | 2305 |
2298 | 2306 |
2299 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 2307 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
2300 FlowGraphCompiler* compiler) { | 2308 FlowGraphCompiler* compiler) { |
2301 Register instantiator_reg = locs()->in(0).reg(); | 2309 Register instantiator_type_args_reg = locs()->in(0).reg(); |
| 2310 Register function_type_args_reg = locs()->in(1).reg(); |
2302 Register result_reg = locs()->out(0).reg(); | 2311 Register result_reg = locs()->out(0).reg(); |
2303 ASSERT(instantiator_reg == EAX); | 2312 ASSERT(instantiator_type_args_reg == EAX); |
2304 ASSERT(instantiator_reg == result_reg); | 2313 ASSERT(instantiator_type_args_reg == result_reg); |
2305 | 2314 |
2306 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2315 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
| 2316 // 'function_type_args_reg' is a TypeArguments object (or null). |
2307 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2317 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
2308 !type_arguments().CanShareInstantiatorTypeArguments( | 2318 !type_arguments().CanShareInstantiatorTypeArguments( |
2309 instantiator_class())); | 2319 instantiator_class())); |
2310 // If the instantiator is null and if the type argument vector | 2320 // If both the instantiator and function type arguments are null and if the |
2311 // instantiated from null becomes a vector of dynamic, then use null as | 2321 // type argument vector instantiated from null becomes a vector of dynamic, |
2312 // the type arguments. | 2322 // then use null as the type arguments. |
2313 Label type_arguments_instantiated; | 2323 Label type_arguments_instantiated; |
2314 const intptr_t len = type_arguments().Length(); | 2324 const intptr_t len = type_arguments().Length(); |
2315 if (type_arguments().IsRawInstantiatedRaw(len)) { | 2325 if (type_arguments().IsRawWhenInstantiatedFromRaw(len)) { |
| 2326 Label non_null_type_args; |
2316 const Immediate& raw_null = | 2327 const Immediate& raw_null = |
2317 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 2328 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
2318 __ cmpl(instantiator_reg, raw_null); | 2329 __ cmpl(instantiator_type_args_reg, raw_null); |
| 2330 __ j(NOT_EQUAL, &non_null_type_args, Assembler::kNearJump); |
| 2331 __ cmpl(function_type_args_reg, raw_null); |
2319 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | 2332 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
| 2333 __ Bind(&non_null_type_args); |
2320 } | 2334 } |
2321 // Lookup cache before calling runtime. | 2335 // Lookup cache before calling runtime. |
2322 // TODO(fschneider): Consider moving this into a shared stub to reduce | 2336 // TODO(regis): Consider moving this into a shared stub to reduce |
2323 // generated code size. | 2337 // generated code size. |
2324 __ LoadObject(EDI, type_arguments()); | 2338 __ LoadObject(EDI, type_arguments()); |
2325 __ movl(EDI, FieldAddress(EDI, TypeArguments::instantiations_offset())); | 2339 __ movl(EDI, FieldAddress(EDI, TypeArguments::instantiations_offset())); |
2326 __ leal(EDI, FieldAddress(EDI, Array::data_offset())); | 2340 __ leal(EDI, FieldAddress(EDI, Array::data_offset())); |
2327 // The instantiations cache is initialized with Object::zero_array() and is | 2341 // The instantiations cache is initialized with Object::zero_array() and is |
2328 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2342 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
2329 Label loop, found, slow_case; | 2343 Label loop, next, found, slow_case; |
2330 __ Bind(&loop); | 2344 __ Bind(&loop); |
2331 __ movl(EDX, Address(EDI, 0 * kWordSize)); // Cached instantiator. | 2345 __ movl(EDX, Address(EDI, 0 * kWordSize)); // Cached instantiator type args. |
2332 __ cmpl(EDX, EAX); | 2346 __ cmpl(EDX, instantiator_type_args_reg); |
| 2347 __ j(NOT_EQUAL, &next, Assembler::kNearJump); |
| 2348 __ movl(ECX, Address(EDI, 1 * kWordSize)); // Cached function type args. |
| 2349 __ cmpl(ECX, function_type_args_reg); |
2333 __ j(EQUAL, &found, Assembler::kNearJump); | 2350 __ j(EQUAL, &found, Assembler::kNearJump); |
2334 __ addl(EDI, Immediate(2 * kWordSize)); | 2351 __ Bind(&next); |
| 2352 __ addl(EDI, Immediate(StubCode::kInstantiationSizeInWords * kWordSize)); |
2335 __ cmpl(EDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 2353 __ cmpl(EDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
2336 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 2354 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
2337 __ jmp(&slow_case, Assembler::kNearJump); | 2355 __ jmp(&slow_case, Assembler::kNearJump); |
2338 __ Bind(&found); | 2356 __ Bind(&found); |
2339 __ movl(EAX, Address(EDI, 1 * kWordSize)); // Cached instantiated args. | 2357 __ movl(result_reg, Address(EDI, 2 * kWordSize)); // Cached instantiated ta. |
2340 __ jmp(&type_arguments_instantiated, Assembler::kNearJump); | 2358 __ jmp(&type_arguments_instantiated, Assembler::kNearJump); |
2341 | 2359 |
2342 __ Bind(&slow_case); | 2360 __ Bind(&slow_case); |
2343 // Instantiate non-null type arguments. | 2361 // Instantiate non-null type arguments. |
2344 // A runtime call to instantiate the type arguments is required. | 2362 // A runtime call to instantiate the type arguments is required. |
2345 __ PushObject(Object::null_object()); // Make room for the result. | 2363 __ PushObject(Object::null_object()); // Make room for the result. |
2346 __ PushObject(type_arguments()); | 2364 __ PushObject(type_arguments()); |
2347 __ pushl(instantiator_reg); // Push instantiator type arguments. | 2365 __ pushl(instantiator_type_args_reg); // Push instantiator type arguments. |
| 2366 __ pushl(function_type_args_reg); // Push function type arguments. |
2348 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2367 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2349 kInstantiateTypeArgumentsRuntimeEntry, 2, | 2368 kInstantiateTypeArgumentsRuntimeEntry, 3, |
2350 locs()); | 2369 locs()); |
2351 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2370 __ Drop(3); // Drop 2 type argument vectors and uninstantiated args. |
2352 __ popl(result_reg); // Pop instantiated type arguments. | 2371 __ popl(result_reg); // Pop instantiated type arguments. |
2353 __ Bind(&type_arguments_instantiated); | 2372 __ Bind(&type_arguments_instantiated); |
2354 } | 2373 } |
2355 | 2374 |
2356 | 2375 |
2357 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( | 2376 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( |
2358 Zone* zone, | 2377 Zone* zone, |
2359 bool opt) const { | 2378 bool opt) const { |
2360 ASSERT(opt); | 2379 ASSERT(opt); |
2361 const intptr_t kNumInputs = 0; | 2380 const intptr_t kNumInputs = 0; |
(...skipping 4572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6934 __ Drop(1); | 6953 __ Drop(1); |
6935 __ popl(result); | 6954 __ popl(result); |
6936 } | 6955 } |
6937 | 6956 |
6938 | 6957 |
6939 } // namespace dart | 6958 } // namespace dart |
6940 | 6959 |
6941 #undef __ | 6960 #undef __ |
6942 | 6961 |
6943 #endif // defined TARGET_ARCH_IA32 | 6962 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |