OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
326 default: | 326 default: |
327 UNREACHABLE(); | 327 UNREACHABLE(); |
328 break; | 328 break; |
329 } | 329 } |
330 } | 330 } |
331 } | 331 } |
332 | 332 |
333 | 333 |
334 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, | 334 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, |
335 bool opt) const { | 335 bool opt) const { |
336 const intptr_t kNumInputs = 2; | 336 const intptr_t kNumInputs = 3; |
337 const intptr_t kNumTemps = 0; | 337 const intptr_t kNumTemps = 0; |
338 LocationSummary* summary = new (zone) | 338 LocationSummary* summary = new (zone) |
339 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 339 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
340 summary->set_in(0, Location::RegisterLocation(R0)); // Value. | 340 summary->set_in(0, Location::RegisterLocation(R0)); // Value. |
341 summary->set_in(1, Location::RegisterLocation(R1)); // Type arguments. | 341 summary->set_in(1, Location::RegisterLocation(R1)); // Instant. type args. |
342 summary->set_in(2, Location::RegisterLocation(R2)); // Function type args. | |
342 summary->set_out(0, Location::RegisterLocation(R0)); | 343 summary->set_out(0, Location::RegisterLocation(R0)); |
343 return summary; | 344 return summary; |
344 } | 345 } |
345 | 346 |
346 | 347 |
347 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, | 348 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, |
348 bool opt) const { | 349 bool opt) const { |
349 const intptr_t kNumInputs = 1; | 350 const intptr_t kNumInputs = 1; |
350 const intptr_t kNumTemps = 0; | 351 const intptr_t kNumTemps = 0; |
351 LocationSummary* locs = new (zone) | 352 LocationSummary* locs = new (zone) |
(...skipping 1732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2084 CanValueBeSmi()); | 2085 CanValueBeSmi()); |
2085 } else { | 2086 } else { |
2086 __ StoreIntoObjectOffsetNoBarrier(temp, Field::static_value_offset(), | 2087 __ StoreIntoObjectOffsetNoBarrier(temp, Field::static_value_offset(), |
2087 value); | 2088 value); |
2088 } | 2089 } |
2089 } | 2090 } |
2090 | 2091 |
2091 | 2092 |
2092 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, | 2093 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, |
2093 bool opt) const { | 2094 bool opt) const { |
2094 const intptr_t kNumInputs = 2; | 2095 const intptr_t kNumInputs = 3; |
2095 const intptr_t kNumTemps = 0; | 2096 const intptr_t kNumTemps = 0; |
2096 LocationSummary* summary = new (zone) | 2097 LocationSummary* summary = new (zone) |
2097 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2098 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2098 summary->set_in(0, Location::RegisterLocation(R0)); | 2099 summary->set_in(0, Location::RegisterLocation(R0)); // Instance. |
2099 summary->set_in(1, Location::RegisterLocation(R1)); | 2100 summary->set_in(1, Location::RegisterLocation(R1)); // Instant. type args. |
2101 summary->set_in(2, Location::RegisterLocation(R2)); // Function type args. | |
2100 summary->set_out(0, Location::RegisterLocation(R0)); | 2102 summary->set_out(0, Location::RegisterLocation(R0)); |
2101 return summary; | 2103 return summary; |
2102 } | 2104 } |
2103 | 2105 |
2104 | 2106 |
2105 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2107 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2106 ASSERT(locs()->in(0).reg() == R0); // Value. | 2108 ASSERT(locs()->in(0).reg() == R0); // Value. |
2107 ASSERT(locs()->in(1).reg() == R1); // Instantiator type arguments. | 2109 ASSERT(locs()->in(1).reg() == R1); // Instantiator type arguments. |
2110 ASSERT(locs()->in(2).reg() == R2); // Function type arguments. | |
2108 | 2111 |
2109 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); | 2112 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); |
2110 ASSERT(locs()->out(0).reg() == R0); | 2113 ASSERT(locs()->out(0).reg() == R0); |
2111 } | 2114 } |
2112 | 2115 |
2113 | 2116 |
2114 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, | 2117 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, |
2115 bool opt) const { | 2118 bool opt) const { |
2116 const intptr_t kNumInputs = 2; | 2119 const intptr_t kNumInputs = 2; |
2117 const intptr_t kNumTemps = 0; | 2120 const intptr_t kNumTemps = 0; |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2337 | 2340 |
2338 __ Bind(&load_pointer); | 2341 __ Bind(&load_pointer); |
2339 } | 2342 } |
2340 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes()); | 2343 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes()); |
2341 __ Bind(&done); | 2344 __ Bind(&done); |
2342 } | 2345 } |
2343 | 2346 |
2344 | 2347 |
2345 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, | 2348 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, |
2346 bool opt) const { | 2349 bool opt) const { |
2347 const intptr_t kNumInputs = 1; | 2350 const intptr_t kNumInputs = 2; |
2348 const intptr_t kNumTemps = 0; | 2351 const intptr_t kNumTemps = 0; |
2349 LocationSummary* locs = new (zone) | 2352 LocationSummary* locs = new (zone) |
2350 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2353 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2351 locs->set_in(0, Location::RegisterLocation(R0)); | 2354 locs->set_in(0, Location::RegisterLocation(R0)); // Instant. type args. |
2355 locs->set_in(1, Location::RegisterLocation(R1)); // Function type args. | |
2352 locs->set_out(0, Location::RegisterLocation(R0)); | 2356 locs->set_out(0, Location::RegisterLocation(R0)); |
2353 return locs; | 2357 return locs; |
2354 } | 2358 } |
2355 | 2359 |
2356 | 2360 |
2357 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2361 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2358 const Register instantiator_reg = locs()->in(0).reg(); | 2362 const Register instantiator_type_args_reg = locs()->in(0).reg(); |
2363 const Register function_type_args_reg = locs()->in(1).reg(); | |
2359 const Register result_reg = locs()->out(0).reg(); | 2364 const Register result_reg = locs()->out(0).reg(); |
2360 | 2365 |
2361 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2366 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
2367 // 'function_type_args_reg' is a TypeArguments object (or null). | |
2362 // A runtime call to instantiate the type is required. | 2368 // A runtime call to instantiate the type is required. |
2363 __ PushObject(Object::null_object()); // Make room for the result. | 2369 __ PushObject(Object::null_object()); // Make room for the result. |
2364 __ PushObject(type()); | 2370 __ PushObject(type()); |
2365 __ Push(instantiator_reg); // Push instantiator type arguments. | 2371 __ Push(instantiator_type_args_reg); // Push instantiator type arguments. |
zra
2017/04/07 17:36:31
PushPair
regis
2017/04/11 04:23:08
Done.
| |
2372 __ Push(function_type_args_reg); // Push function type arguments. | |
2366 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2373 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2367 kInstantiateTypeRuntimeEntry, 2, locs()); | 2374 kInstantiateTypeRuntimeEntry, 3, locs()); |
2368 __ Drop(2); // Drop instantiator and uninstantiated type. | 2375 __ Drop(3); // Drop 2 type argument vectors and uninstantiated type. |
2369 __ Pop(result_reg); // Pop instantiated type. | 2376 __ Pop(result_reg); // Pop instantiated type. |
2370 ASSERT(instantiator_reg == result_reg); | 2377 ASSERT(instantiator_type_args_reg == result_reg); |
2371 } | 2378 } |
2372 | 2379 |
2373 | 2380 |
2374 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( | 2381 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
2375 Zone* zone, | 2382 Zone* zone, |
2376 bool opt) const { | 2383 bool opt) const { |
2377 const intptr_t kNumInputs = 1; | 2384 const intptr_t kNumInputs = 2; |
2378 const intptr_t kNumTemps = 0; | 2385 const intptr_t kNumTemps = 0; |
2379 LocationSummary* locs = new (zone) | 2386 LocationSummary* locs = new (zone) |
2380 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2387 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2381 locs->set_in(0, Location::RegisterLocation(R0)); | 2388 locs->set_in(0, Location::RegisterLocation(R0)); // Instant. type args. |
2389 locs->set_in(1, Location::RegisterLocation(R1)); // Function type args. | |
2382 locs->set_out(0, Location::RegisterLocation(R0)); | 2390 locs->set_out(0, Location::RegisterLocation(R0)); |
2383 return locs; | 2391 return locs; |
2384 } | 2392 } |
2385 | 2393 |
2386 | 2394 |
2387 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 2395 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
2388 FlowGraphCompiler* compiler) { | 2396 FlowGraphCompiler* compiler) { |
2389 const Register instantiator_reg = locs()->in(0).reg(); | 2397 const Register instantiator_type_args_reg = locs()->in(0).reg(); |
2398 const Register function_type_args_reg = locs()->in(1).reg(); | |
2390 const Register result_reg = locs()->out(0).reg(); | 2399 const Register result_reg = locs()->out(0).reg(); |
2391 ASSERT(instantiator_reg == R0); | 2400 ASSERT(instantiator_type_args_reg == R0); |
2392 ASSERT(instantiator_reg == result_reg); | 2401 ASSERT(instantiator_type_args_reg == result_reg); |
2393 | 2402 |
2394 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2403 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
2404 // 'function_type_args_reg' is a TypeArguments object (or null). | |
2395 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2405 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
2396 !type_arguments().CanShareInstantiatorTypeArguments( | 2406 !type_arguments().CanShareInstantiatorTypeArguments( |
2397 instantiator_class())); | 2407 instantiator_class())); |
2398 // If the instantiator is null and if the type argument vector | 2408 // If both the instantiator and function type arguments are null and if the |
2399 // instantiated from null becomes a vector of dynamic, then use null as | 2409 // type argument vector instantiated from null becomes a vector of dynamic, |
2400 // the type arguments. | 2410 // then use null as the type arguments. |
2401 Label type_arguments_instantiated; | 2411 Label type_arguments_instantiated; |
2402 const intptr_t len = type_arguments().Length(); | 2412 const intptr_t len = type_arguments().Length(); |
2403 if (type_arguments().IsRawInstantiatedRaw(len)) { | 2413 if (type_arguments().IsRawInstantiatedRaw(len)) { |
2404 __ CompareObject(instantiator_reg, Object::null_object()); | 2414 Label non_null_type_args; |
2415 __ CompareObject(instantiator_type_args_reg, Object::null_object()); | |
2416 __ b(&non_null_type_args, NE); | |
2417 __ CompareObject(function_type_args_reg, Object::null_object()); | |
2405 __ b(&type_arguments_instantiated, EQ); | 2418 __ b(&type_arguments_instantiated, EQ); |
2419 __ Bind(&non_null_type_args); | |
2406 } | 2420 } |
2407 | 2421 |
2408 __ LoadObject(R2, type_arguments()); | 2422 // Lookup cache before calling runtime. |
2409 __ LoadFieldFromOffset(R2, R2, TypeArguments::instantiations_offset()); | 2423 // TODO(regis): Consider moving this into a shared stub to reduce |
2410 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); | 2424 // generated code size. |
2425 __ LoadObject(R3, type_arguments()); | |
2426 __ LoadFieldFromOffset(R3, R3, TypeArguments::instantiations_offset()); | |
2427 __ AddImmediate(R3, R3, Array::data_offset() - kHeapObjectTag); | |
2411 // The instantiations cache is initialized with Object::zero_array() and is | 2428 // The instantiations cache is initialized with Object::zero_array() and is |
2412 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2429 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
2413 Label loop, found, slow_case; | 2430 Label loop, next, found, slow_case; |
2414 __ Bind(&loop); | 2431 __ Bind(&loop); |
2415 __ LoadFromOffset(R1, R2, 0 * kWordSize); // Cached instantiator. | 2432 __ LoadFromOffset(R2, R3, 0 * kWordSize); // Cached instantiator type args. |
2416 __ CompareRegisters(R1, R0); | 2433 __ CompareRegisters(R2, instantiator_type_args_reg); |
2434 __ b(&next, NE); | |
2435 __ LoadFromOffset(TMP, R3, 1 * kWordSize); // Cached function type args. | |
2436 __ CompareRegisters(TMP, function_type_args_reg); | |
2417 __ b(&found, EQ); | 2437 __ b(&found, EQ); |
2418 __ AddImmediate(R2, R2, 2 * kWordSize); | 2438 __ Bind(&next); |
2419 __ CompareImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); | 2439 __ AddImmediate(R3, R3, StubCode::kInstantiationSizeInWords * kWordSize); |
2440 __ CompareImmediate(R2, Smi::RawValue(StubCode::kNoInstantiator)); | |
2420 __ b(&loop, NE); | 2441 __ b(&loop, NE); |
2421 __ b(&slow_case); | 2442 __ b(&slow_case); |
2422 __ Bind(&found); | 2443 __ Bind(&found); |
2423 __ LoadFromOffset(R0, R2, 1 * kWordSize); // Cached instantiated args. | 2444 __ LoadFromOffset(result_reg, R3, 2 * kWordSize); // Cached instantiated ta. |
2424 __ b(&type_arguments_instantiated); | 2445 __ b(&type_arguments_instantiated); |
2425 | 2446 |
2426 __ Bind(&slow_case); | 2447 __ Bind(&slow_case); |
2427 // Instantiate non-null type arguments. | 2448 // Instantiate non-null type arguments. |
2428 // A runtime call to instantiate the type arguments is required. | 2449 // A runtime call to instantiate the type arguments is required. |
2429 __ PushObject(Object::null_object()); // Make room for the result. | 2450 __ PushObject(Object::null_object()); // Make room for the result. |
2430 __ PushObject(type_arguments()); | 2451 __ PushObject(type_arguments()); |
2431 __ Push(instantiator_reg); // Push instantiator type arguments. | 2452 __ Push(instantiator_type_args_reg); // Push instantiator type arguments. |
zra
2017/04/07 17:36:31
PushPair
regis
2017/04/11 04:23:08
Done.
| |
2453 __ Push(function_type_args_reg); // Push function type arguments. | |
2432 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2454 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2433 kInstantiateTypeArgumentsRuntimeEntry, 2, | 2455 kInstantiateTypeArgumentsRuntimeEntry, 3, |
2434 locs()); | 2456 locs()); |
2435 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2457 __ Drop(3); // Drop 2 type argument vectors and uninstantiated args. |
2436 __ Pop(result_reg); // Pop instantiated type arguments. | 2458 __ Pop(result_reg); // Pop instantiated type arguments. |
2437 __ Bind(&type_arguments_instantiated); | 2459 __ Bind(&type_arguments_instantiated); |
2438 } | 2460 } |
2439 | 2461 |
2440 | 2462 |
2441 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( | 2463 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( |
2442 Zone* zone, | 2464 Zone* zone, |
2443 bool opt) const { | 2465 bool opt) const { |
2444 ASSERT(opt); | 2466 ASSERT(opt); |
2445 const intptr_t kNumInputs = 0; | 2467 const intptr_t kNumInputs = 0; |
(...skipping 3638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6084 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 6106 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
6085 kGrowRegExpStackRuntimeEntry, 1, locs()); | 6107 kGrowRegExpStackRuntimeEntry, 1, locs()); |
6086 __ Drop(1); | 6108 __ Drop(1); |
6087 __ Pop(result); | 6109 __ Pop(result); |
6088 } | 6110 } |
6089 | 6111 |
6090 | 6112 |
6091 } // namespace dart | 6113 } // namespace dart |
6092 | 6114 |
6093 #endif // defined TARGET_ARCH_ARM64 | 6115 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |