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 __ PushPair(function_type_args_reg, instantiator_type_args_reg); |
2366 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2372 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2367 kInstantiateTypeRuntimeEntry, 2, locs()); | 2373 kInstantiateTypeRuntimeEntry, 3, locs()); |
2368 __ Drop(2); // Drop instantiator and uninstantiated type. | 2374 __ Drop(3); // Drop 2 type argument vectors and uninstantiated type. |
2369 __ Pop(result_reg); // Pop instantiated type. | 2375 __ Pop(result_reg); // Pop instantiated type. |
2370 ASSERT(instantiator_reg == result_reg); | 2376 ASSERT(instantiator_type_args_reg == result_reg); |
2371 } | 2377 } |
2372 | 2378 |
2373 | 2379 |
2374 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( | 2380 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
2375 Zone* zone, | 2381 Zone* zone, |
2376 bool opt) const { | 2382 bool opt) const { |
2377 const intptr_t kNumInputs = 1; | 2383 const intptr_t kNumInputs = 2; |
2378 const intptr_t kNumTemps = 0; | 2384 const intptr_t kNumTemps = 0; |
2379 LocationSummary* locs = new (zone) | 2385 LocationSummary* locs = new (zone) |
2380 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2386 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
2381 locs->set_in(0, Location::RegisterLocation(R0)); | 2387 locs->set_in(0, Location::RegisterLocation(R0)); // Instant. type args. |
| 2388 locs->set_in(1, Location::RegisterLocation(R1)); // Function type args. |
2382 locs->set_out(0, Location::RegisterLocation(R0)); | 2389 locs->set_out(0, Location::RegisterLocation(R0)); |
2383 return locs; | 2390 return locs; |
2384 } | 2391 } |
2385 | 2392 |
2386 | 2393 |
2387 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 2394 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
2388 FlowGraphCompiler* compiler) { | 2395 FlowGraphCompiler* compiler) { |
2389 const Register instantiator_reg = locs()->in(0).reg(); | 2396 const Register instantiator_type_args_reg = locs()->in(0).reg(); |
| 2397 const Register function_type_args_reg = locs()->in(1).reg(); |
2390 const Register result_reg = locs()->out(0).reg(); | 2398 const Register result_reg = locs()->out(0).reg(); |
2391 ASSERT(instantiator_reg == R0); | 2399 ASSERT(instantiator_type_args_reg == R0); |
2392 ASSERT(instantiator_reg == result_reg); | 2400 ASSERT(instantiator_type_args_reg == result_reg); |
2393 | 2401 |
2394 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2402 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
| 2403 // 'function_type_args_reg' is a TypeArguments object (or null). |
2395 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2404 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
2396 !type_arguments().CanShareInstantiatorTypeArguments( | 2405 !type_arguments().CanShareInstantiatorTypeArguments( |
2397 instantiator_class())); | 2406 instantiator_class())); |
2398 // If the instantiator is null and if the type argument vector | 2407 // 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 | 2408 // type argument vector instantiated from null becomes a vector of dynamic, |
2400 // the type arguments. | 2409 // then use null as the type arguments. |
2401 Label type_arguments_instantiated; | 2410 Label type_arguments_instantiated; |
2402 const intptr_t len = type_arguments().Length(); | 2411 const intptr_t len = type_arguments().Length(); |
2403 if (type_arguments().IsRawInstantiatedRaw(len)) { | 2412 if (type_arguments().IsRawWhenInstantiatedFromRaw(len)) { |
2404 __ CompareObject(instantiator_reg, Object::null_object()); | 2413 Label non_null_type_args; |
| 2414 __ CompareObject(instantiator_type_args_reg, Object::null_object()); |
| 2415 __ b(&non_null_type_args, NE); |
| 2416 __ CompareObject(function_type_args_reg, Object::null_object()); |
2405 __ b(&type_arguments_instantiated, EQ); | 2417 __ b(&type_arguments_instantiated, EQ); |
| 2418 __ Bind(&non_null_type_args); |
2406 } | 2419 } |
2407 | 2420 |
2408 __ LoadObject(R2, type_arguments()); | 2421 // Lookup cache before calling runtime. |
2409 __ LoadFieldFromOffset(R2, R2, TypeArguments::instantiations_offset()); | 2422 // TODO(regis): Consider moving this into a shared stub to reduce |
2410 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); | 2423 // generated code size. |
| 2424 __ LoadObject(R3, type_arguments()); |
| 2425 __ LoadFieldFromOffset(R3, R3, TypeArguments::instantiations_offset()); |
| 2426 __ AddImmediate(R3, R3, Array::data_offset() - kHeapObjectTag); |
2411 // The instantiations cache is initialized with Object::zero_array() and is | 2427 // The instantiations cache is initialized with Object::zero_array() and is |
2412 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2428 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
2413 Label loop, found, slow_case; | 2429 Label loop, next, found, slow_case; |
2414 __ Bind(&loop); | 2430 __ Bind(&loop); |
2415 __ LoadFromOffset(R1, R2, 0 * kWordSize); // Cached instantiator. | 2431 __ LoadFromOffset(R2, R3, 0 * kWordSize); // Cached instantiator type args. |
2416 __ CompareRegisters(R1, R0); | 2432 __ CompareRegisters(R2, instantiator_type_args_reg); |
| 2433 __ b(&next, NE); |
| 2434 __ LoadFromOffset(TMP, R3, 1 * kWordSize); // Cached function type args. |
| 2435 __ CompareRegisters(TMP, function_type_args_reg); |
2417 __ b(&found, EQ); | 2436 __ b(&found, EQ); |
2418 __ AddImmediate(R2, R2, 2 * kWordSize); | 2437 __ Bind(&next); |
2419 __ CompareImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); | 2438 __ AddImmediate(R3, R3, StubCode::kInstantiationSizeInWords * kWordSize); |
| 2439 __ CompareImmediate(R2, Smi::RawValue(StubCode::kNoInstantiator)); |
2420 __ b(&loop, NE); | 2440 __ b(&loop, NE); |
2421 __ b(&slow_case); | 2441 __ b(&slow_case); |
2422 __ Bind(&found); | 2442 __ Bind(&found); |
2423 __ LoadFromOffset(R0, R2, 1 * kWordSize); // Cached instantiated args. | 2443 __ LoadFromOffset(result_reg, R3, 2 * kWordSize); // Cached instantiated ta. |
2424 __ b(&type_arguments_instantiated); | 2444 __ b(&type_arguments_instantiated); |
2425 | 2445 |
2426 __ Bind(&slow_case); | 2446 __ Bind(&slow_case); |
2427 // Instantiate non-null type arguments. | 2447 // Instantiate non-null type arguments. |
2428 // A runtime call to instantiate the type arguments is required. | 2448 // A runtime call to instantiate the type arguments is required. |
2429 __ PushObject(Object::null_object()); // Make room for the result. | 2449 __ PushObject(Object::null_object()); // Make room for the result. |
2430 __ PushObject(type_arguments()); | 2450 __ PushObject(type_arguments()); |
2431 __ Push(instantiator_reg); // Push instantiator type arguments. | 2451 __ PushPair(function_type_args_reg, instantiator_type_args_reg); |
2432 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2452 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
2433 kInstantiateTypeArgumentsRuntimeEntry, 2, | 2453 kInstantiateTypeArgumentsRuntimeEntry, 3, |
2434 locs()); | 2454 locs()); |
2435 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 2455 __ Drop(3); // Drop 2 type argument vectors and uninstantiated args. |
2436 __ Pop(result_reg); // Pop instantiated type arguments. | 2456 __ Pop(result_reg); // Pop instantiated type arguments. |
2437 __ Bind(&type_arguments_instantiated); | 2457 __ Bind(&type_arguments_instantiated); |
2438 } | 2458 } |
2439 | 2459 |
2440 | 2460 |
2441 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( | 2461 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( |
2442 Zone* zone, | 2462 Zone* zone, |
2443 bool opt) const { | 2463 bool opt) const { |
2444 ASSERT(opt); | 2464 ASSERT(opt); |
2445 const intptr_t kNumInputs = 0; | 2465 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(), | 6104 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
6085 kGrowRegExpStackRuntimeEntry, 1, locs()); | 6105 kGrowRegExpStackRuntimeEntry, 1, locs()); |
6086 __ Drop(1); | 6106 __ Drop(1); |
6087 __ Pop(result); | 6107 __ Pop(result); |
6088 } | 6108 } |
6089 | 6109 |
6090 | 6110 |
6091 } // namespace dart | 6111 } // namespace dart |
6092 | 6112 |
6093 #endif // defined TARGET_ARCH_ARM64 | 6113 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |