| 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_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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 | 402 |
| 403 default: | 403 default: |
| 404 UNREACHABLE(); | 404 UNREACHABLE(); |
| 405 } | 405 } |
| 406 } | 406 } |
| 407 } | 407 } |
| 408 | 408 |
| 409 | 409 |
| 410 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, | 410 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone, |
| 411 bool opt) const { | 411 bool opt) const { |
| 412 const intptr_t kNumInputs = 2; | 412 const intptr_t kNumInputs = 3; |
| 413 const intptr_t kNumTemps = 0; | 413 const intptr_t kNumTemps = 0; |
| 414 LocationSummary* summary = new (zone) | 414 LocationSummary* summary = new (zone) |
| 415 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 415 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
| 416 summary->set_in(0, Location::RegisterLocation(A0)); // Value. | 416 summary->set_in(0, Location::RegisterLocation(A0)); // Value. |
| 417 summary->set_in(1, Location::RegisterLocation(A1)); // Type arguments. | 417 summary->set_in(1, Location::RegisterLocation(A1)); // Instant. type args. |
| 418 summary->set_in(2, Location::RegisterLocation(A2)); // Function type args. |
| 418 summary->set_out(0, Location::RegisterLocation(A0)); | 419 summary->set_out(0, Location::RegisterLocation(A0)); |
| 419 return summary; | 420 return summary; |
| 420 } | 421 } |
| 421 | 422 |
| 422 | 423 |
| 423 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, | 424 LocationSummary* AssertBooleanInstr::MakeLocationSummary(Zone* zone, |
| 424 bool opt) const { | 425 bool opt) const { |
| 425 const intptr_t kNumInputs = 1; | 426 const intptr_t kNumInputs = 1; |
| 426 const intptr_t kNumTemps = 0; | 427 const intptr_t kNumTemps = 0; |
| 427 LocationSummary* locs = new (zone) | 428 LocationSummary* locs = new (zone) |
| (...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 value, CanValueBeSmi()); | 2229 value, CanValueBeSmi()); |
| 2229 } else { | 2230 } else { |
| 2230 __ StoreIntoObjectNoBarrier( | 2231 __ StoreIntoObjectNoBarrier( |
| 2231 temp, FieldAddress(temp, Field::static_value_offset()), value); | 2232 temp, FieldAddress(temp, Field::static_value_offset()), value); |
| 2232 } | 2233 } |
| 2233 } | 2234 } |
| 2234 | 2235 |
| 2235 | 2236 |
| 2236 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, | 2237 LocationSummary* InstanceOfInstr::MakeLocationSummary(Zone* zone, |
| 2237 bool opt) const { | 2238 bool opt) const { |
| 2238 const intptr_t kNumInputs = 2; | 2239 const intptr_t kNumInputs = 3; |
| 2239 const intptr_t kNumTemps = 0; | 2240 const intptr_t kNumTemps = 0; |
| 2240 LocationSummary* summary = new (zone) | 2241 LocationSummary* summary = new (zone) |
| 2241 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2242 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2242 summary->set_in(0, Location::RegisterLocation(A0)); | 2243 summary->set_in(0, Location::RegisterLocation(A0)); // Instance. |
| 2243 summary->set_in(1, Location::RegisterLocation(A1)); | 2244 summary->set_in(1, Location::RegisterLocation(A1)); // Instant. type args. |
| 2245 summary->set_in(2, Location::RegisterLocation(A2)); // Function type args. |
| 2244 summary->set_out(0, Location::RegisterLocation(V0)); | 2246 summary->set_out(0, Location::RegisterLocation(V0)); |
| 2245 return summary; | 2247 return summary; |
| 2246 } | 2248 } |
| 2247 | 2249 |
| 2248 | 2250 |
| 2249 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2251 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2250 ASSERT(locs()->in(0).reg() == A0); // Value. | 2252 ASSERT(locs()->in(0).reg() == A0); // Value. |
| 2251 ASSERT(locs()->in(1).reg() == A1); // Instantiator type arguments. | 2253 ASSERT(locs()->in(1).reg() == A1); // Instantiator type arguments. |
| 2254 ASSERT(locs()->in(2).reg() == A2); // Function type arguments. |
| 2252 | 2255 |
| 2253 __ Comment("InstanceOfInstr"); | 2256 __ Comment("InstanceOfInstr"); |
| 2254 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); | 2257 compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs()); |
| 2255 ASSERT(locs()->out(0).reg() == V0); | 2258 ASSERT(locs()->out(0).reg() == V0); |
| 2256 } | 2259 } |
| 2257 | 2260 |
| 2258 | 2261 |
| 2259 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, | 2262 LocationSummary* CreateArrayInstr::MakeLocationSummary(Zone* zone, |
| 2260 bool opt) const { | 2263 bool opt) const { |
| 2261 const intptr_t kNumInputs = 2; | 2264 const intptr_t kNumInputs = 2; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2448 | 2451 |
| 2449 __ Bind(&load_pointer); | 2452 __ Bind(&load_pointer); |
| 2450 } | 2453 } |
| 2451 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes()); | 2454 __ LoadFieldFromOffset(result_reg, instance_reg, offset_in_bytes()); |
| 2452 __ Bind(&done); | 2455 __ Bind(&done); |
| 2453 } | 2456 } |
| 2454 | 2457 |
| 2455 | 2458 |
| 2456 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, | 2459 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(Zone* zone, |
| 2457 bool opt) const { | 2460 bool opt) const { |
| 2458 const intptr_t kNumInputs = 1; | 2461 const intptr_t kNumInputs = 2; |
| 2459 const intptr_t kNumTemps = 0; | 2462 const intptr_t kNumTemps = 0; |
| 2460 LocationSummary* locs = new (zone) | 2463 LocationSummary* locs = new (zone) |
| 2461 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2464 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2462 locs->set_in(0, Location::RegisterLocation(T0)); | 2465 locs->set_in(0, Location::RegisterLocation(T0)); // Instant. type args. |
| 2466 locs->set_in(1, Location::RegisterLocation(T1)); // Function type args. |
| 2463 locs->set_out(0, Location::RegisterLocation(T0)); | 2467 locs->set_out(0, Location::RegisterLocation(T0)); |
| 2464 return locs; | 2468 return locs; |
| 2465 } | 2469 } |
| 2466 | 2470 |
| 2467 | 2471 |
| 2468 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2472 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2469 __ Comment("InstantiateTypeInstr"); | 2473 __ Comment("InstantiateTypeInstr"); |
| 2470 Register instantiator_reg = locs()->in(0).reg(); | 2474 Register instantiator_type_args_reg = locs()->in(0).reg(); |
| 2475 Register function_type_args_reg = locs()->in(1).reg(); |
| 2471 Register result_reg = locs()->out(0).reg(); | 2476 Register result_reg = locs()->out(0).reg(); |
| 2472 | 2477 |
| 2473 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2478 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
| 2479 // 'function_type_args_reg' is a TypeArguments object (or null). |
| 2474 // A runtime call to instantiate the type is required. | 2480 // A runtime call to instantiate the type is required. |
| 2475 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2481 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 2476 __ LoadObject(TMP, Object::null_object()); | 2482 __ LoadObject(TMP, Object::null_object()); |
| 2477 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result. | 2483 __ sw(TMP, Address(SP, 3 * kWordSize)); // Make room for the result. |
| 2478 __ LoadObject(TMP, type()); | 2484 __ LoadObject(TMP, type()); |
| 2479 __ sw(TMP, Address(SP, 1 * kWordSize)); | 2485 __ sw(TMP, Address(SP, 2 * kWordSize)); |
| 2480 // Push instantiator type arguments. | 2486 __ sw(instantiator_type_args_reg, Address(SP, 1 * kWordSize)); |
| 2481 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); | 2487 __ sw(function_type_args_reg, Address(SP, 0 * kWordSize)); |
| 2482 | 2488 |
| 2483 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2489 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
| 2484 kInstantiateTypeRuntimeEntry, 2, locs()); | 2490 kInstantiateTypeRuntimeEntry, 3, locs()); |
| 2485 // Pop instantiated type. | 2491 // Pop instantiated type. |
| 2486 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2492 __ lw(result_reg, Address(SP, 3 * kWordSize)); |
| 2493 |
| 2487 // Drop instantiator and uninstantiated type. | 2494 // Drop instantiator and uninstantiated type. |
| 2488 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2495 __ addiu(SP, SP, Immediate(4 * kWordSize)); |
| 2489 ASSERT(instantiator_reg == result_reg); | |
| 2490 } | 2496 } |
| 2491 | 2497 |
| 2492 | 2498 |
| 2493 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( | 2499 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( |
| 2494 Zone* zone, | 2500 Zone* zone, |
| 2495 bool opt) const { | 2501 bool opt) const { |
| 2496 const intptr_t kNumInputs = 1; | 2502 const intptr_t kNumInputs = 2; |
| 2497 const intptr_t kNumTemps = 0; | 2503 const intptr_t kNumTemps = 0; |
| 2498 LocationSummary* locs = new (zone) | 2504 LocationSummary* locs = new (zone) |
| 2499 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 2505 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2500 locs->set_in(0, Location::RegisterLocation(T0)); | 2506 locs->set_in(0, Location::RegisterLocation(T0)); // Instant. type args. |
| 2507 locs->set_in(1, Location::RegisterLocation(T1)); // Function type args. |
| 2501 locs->set_out(0, Location::RegisterLocation(T0)); | 2508 locs->set_out(0, Location::RegisterLocation(T0)); |
| 2502 return locs; | 2509 return locs; |
| 2503 } | 2510 } |
| 2504 | 2511 |
| 2505 | 2512 |
| 2506 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 2513 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
| 2507 FlowGraphCompiler* compiler) { | 2514 FlowGraphCompiler* compiler) { |
| 2508 __ Comment("InstantiateTypeArgumentsInstr"); | 2515 __ Comment("InstantiateTypeArgumentsInstr"); |
| 2509 Register instantiator_reg = locs()->in(0).reg(); | 2516 Register instantiator_type_args_reg = locs()->in(0).reg(); |
| 2517 Register function_type_args_reg = locs()->in(1).reg(); |
| 2510 Register result_reg = locs()->out(0).reg(); | 2518 Register result_reg = locs()->out(0).reg(); |
| 2511 ASSERT(instantiator_reg == T0); | 2519 ASSERT(instantiator_type_args_reg == T0); |
| 2512 ASSERT(instantiator_reg == result_reg); | 2520 ASSERT(instantiator_type_args_reg == result_reg); |
| 2513 | 2521 |
| 2514 // 'instantiator_reg' is the instantiator TypeArguments object (or null). | 2522 // 'instantiator_type_args_reg' is a TypeArguments object (or null). |
| 2523 // 'function_type_args_reg' is a TypeArguments object (or null). |
| 2515 ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2524 ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
| 2516 !type_arguments().CanShareInstantiatorTypeArguments( | 2525 !type_arguments().CanShareInstantiatorTypeArguments( |
| 2517 instantiator_class())); | 2526 instantiator_class())); |
| 2518 // If the instantiator is null and if the type argument vector | 2527 // If both the instantiator and function type arguments are null and if the |
| 2519 // instantiated from null becomes a vector of dynamic, then use null as | 2528 // type argument vector instantiated from null becomes a vector of dynamic, |
| 2520 // the type arguments. | 2529 // then use null as the type arguments. |
| 2521 Label type_arguments_instantiated; | 2530 Label type_arguments_instantiated; |
| 2522 const intptr_t len = type_arguments().Length(); | 2531 const intptr_t len = type_arguments().Length(); |
| 2523 if (type_arguments().IsRawInstantiatedRaw(len)) { | 2532 if (type_arguments().IsRawInstantiatedRaw(len)) { |
| 2524 __ BranchEqual(instantiator_reg, Object::null_object(), | 2533 Label non_null_type_args; |
| 2534 __ BranchNotEqual(instantiator_type_args_reg, Object::null_object(), |
| 2535 &non_null_type_args); |
| 2536 __ BranchEqual(function_type_args_reg, Object::null_object(), |
| 2525 &type_arguments_instantiated); | 2537 &type_arguments_instantiated); |
| 2538 __ Bind(&non_null_type_args); |
| 2526 } | 2539 } |
| 2527 | 2540 |
| 2541 // Lookup cache before calling runtime. |
| 2542 // TODO(regis): Consider moving this into a shared stub to reduce |
| 2543 // generated code size. |
| 2528 __ LoadObject(T2, type_arguments()); | 2544 __ LoadObject(T2, type_arguments()); |
| 2529 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); | 2545 __ lw(T2, FieldAddress(T2, TypeArguments::instantiations_offset())); |
| 2530 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); | 2546 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); |
| 2531 // The instantiations cache is initialized with Object::zero_array() and is | 2547 // The instantiations cache is initialized with Object::zero_array() and is |
| 2532 // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2548 // therefore guaranteed to contain kNoInstantiator. No length check needed. |
| 2533 Label loop, found, slow_case; | 2549 Label loop, next, found, slow_case; |
| 2534 __ Bind(&loop); | 2550 __ Bind(&loop); |
| 2535 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. | 2551 __ lw(T3, Address(T2, 0 * kWordSize)); // Cached instantiator type args. |
| 2536 __ beq(T1, T0, &found); | 2552 __ bne(T3, T0, &next); |
| 2537 __ BranchNotEqual(T1, Immediate(Smi::RawValue(StubCode::kNoInstantiator)), | 2553 __ lw(T4, Address(T2, 1 * kWordSize)); // Cached function type args. |
| 2554 __ beq(T4, T1, &found); |
| 2555 __ Bind(&next); |
| 2556 __ BranchNotEqual(T3, Immediate(Smi::RawValue(StubCode::kNoInstantiator)), |
| 2538 &loop); | 2557 &loop); |
| 2539 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); | 2558 __ delay_slot()->addiu( |
| 2559 T2, T2, Immediate(StubCode::kInstantiationSizeInWords * kWordSize)); |
| 2540 __ b(&slow_case); | 2560 __ b(&slow_case); |
| 2541 __ Bind(&found); | 2561 __ Bind(&found); |
| 2542 __ lw(T0, Address(T2, 1 * kWordSize)); // Cached instantiated args. | 2562 __ lw(T0, Address(T2, 2 * kWordSize)); // Cached instantiated args. |
| 2543 __ b(&type_arguments_instantiated); | 2563 __ b(&type_arguments_instantiated); |
| 2544 | 2564 |
| 2545 __ Bind(&slow_case); | 2565 __ Bind(&slow_case); |
| 2546 // Instantiate non-null type arguments. | 2566 // Instantiate non-null type arguments. |
| 2547 // A runtime call to instantiate the type arguments is required. | 2567 // A runtime call to instantiate the type arguments is required. |
| 2548 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2568 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 2549 __ LoadObject(TMP, Object::null_object()); | 2569 __ LoadObject(TMP, Object::null_object()); |
| 2550 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result. | 2570 __ sw(TMP, Address(SP, 3 * kWordSize)); // Make room for the result. |
| 2551 __ LoadObject(TMP, type_arguments()); | 2571 __ LoadObject(TMP, type_arguments()); |
| 2552 __ sw(TMP, Address(SP, 1 * kWordSize)); | 2572 __ sw(TMP, Address(SP, 2 * kWordSize)); |
| 2553 // Push instantiator type arguments. | 2573 __ sw(instantiator_type_args_reg, Address(SP, 1 * kWordSize)); |
| 2554 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); | 2574 __ sw(function_type_args_reg, Address(SP, 0 * kWordSize)); |
| 2555 | 2575 |
| 2556 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), | 2576 compiler->GenerateRuntimeCall(token_pos(), deopt_id(), |
| 2557 kInstantiateTypeArgumentsRuntimeEntry, 2, | 2577 kInstantiateTypeArgumentsRuntimeEntry, 3, |
| 2558 locs()); | 2578 locs()); |
| 2559 // Pop instantiated type arguments. | 2579 // Pop instantiated type arguments. |
| 2560 __ lw(result_reg, Address(SP, 2 * kWordSize)); | 2580 __ lw(result_reg, Address(SP, 3 * kWordSize)); |
| 2561 // Drop instantiator and uninstantiated type arguments. | 2581 // Drop 2 type argument vectors and uninstantiated type arguments. |
| 2562 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 2582 __ addiu(SP, SP, Immediate(4 * kWordSize)); |
| 2563 __ Bind(&type_arguments_instantiated); | 2583 __ Bind(&type_arguments_instantiated); |
| 2564 } | 2584 } |
| 2565 | 2585 |
| 2566 | 2586 |
| 2567 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( | 2587 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( |
| 2568 Zone* zone, | 2588 Zone* zone, |
| 2569 bool opt) const { | 2589 bool opt) const { |
| 2570 ASSERT(opt); | 2590 ASSERT(opt); |
| 2571 const intptr_t kNumInputs = 0; | 2591 const intptr_t kNumInputs = 0; |
| 2572 const intptr_t kNumTemps = 3; | 2592 const intptr_t kNumTemps = 3; |
| (...skipping 3507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6080 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 6100 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
| 6081 kGrowRegExpStackRuntimeEntry, 1, locs()); | 6101 kGrowRegExpStackRuntimeEntry, 1, locs()); |
| 6082 __ lw(result, Address(SP, 1 * kWordSize)); | 6102 __ lw(result, Address(SP, 1 * kWordSize)); |
| 6083 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 6103 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 6084 } | 6104 } |
| 6085 | 6105 |
| 6086 | 6106 |
| 6087 } // namespace dart | 6107 } // namespace dart |
| 6088 | 6108 |
| 6089 #endif // defined TARGET_ARCH_MIPS | 6109 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |