Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Unified Diff: runtime/vm/flow_graph_compiler_mips.cc

Issue 14076005: Supports FrameLookup vm test on MIPS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/constants_mips.h ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_compiler_mips.cc
===================================================================
--- runtime/vm/flow_graph_compiler_mips.cc (revision 21219)
+++ runtime/vm/flow_graph_compiler_mips.cc (working copy)
@@ -49,13 +49,21 @@
#define __ assembler()->
+// Fall through if bool_register contains null.
void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
Label* is_true,
Label* is_false) {
- UNIMPLEMENTED();
+ Label fall_through;
+ __ BranchEqual(bool_register, reinterpret_cast<intptr_t>(Object::null()),
+ &fall_through);
+ __ BranchEqual(bool_register, Bool::True(), is_true);
+ __ b(is_false);
+ __ Bind(&fall_through);
}
+// A0: instance (must be preserved).
+// A1: instantiator type arguments (if used).
RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
TypeTestStubKind test_kind,
Register instance_reg,
@@ -63,8 +71,28 @@
Register temp_reg,
Label* is_instance_lbl,
Label* is_not_instance_lbl) {
- UNIMPLEMENTED();
- return NULL;
+ ASSERT(instance_reg == A0);
+ ASSERT(temp_reg == kNoRegister); // Unused on MIPS.
+ const SubtypeTestCache& type_test_cache =
+ SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
+ __ LoadObject(A2, type_test_cache);
+ if (test_kind == kTestTypeOneArg) {
+ ASSERT(type_arguments_reg == kNoRegister);
+ __ LoadImmediate(A1, reinterpret_cast<intptr_t>(Object::null()));
+ __ BranchLink(&StubCode::Subtype1TestCacheLabel());
+ } else if (test_kind == kTestTypeTwoArgs) {
+ ASSERT(type_arguments_reg == kNoRegister);
+ __ LoadImmediate(A1, reinterpret_cast<intptr_t>(Object::null()));
+ __ BranchLink(&StubCode::Subtype2TestCacheLabel());
+ } else if (test_kind == kTestTypeThreeArgs) {
+ ASSERT(type_arguments_reg == A1);
+ __ BranchLink(&StubCode::Subtype3TestCacheLabel());
+ } else {
+ UNREACHABLE();
+ }
+ // Result is in V0: null -> not found, otherwise Bool::True or Bool::False.
+ GenerateBoolToJump(V0, is_instance_lbl, is_not_instance_lbl);
+ return type_test_cache.raw();
}
@@ -153,13 +181,35 @@
}
+// Uses SubtypeTestCache to store instance class and result.
+// A0: instance to test.
+// Clobbers A1, A2, T0-T3.
+// Immediate class test already done.
+// TODO(srdjan): Implement a quicker subtype check, as type test
+// arrays can grow too high, but they may be useful when optimizing
+// code (type-feedback).
RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
intptr_t token_pos,
const Class& type_class,
Label* is_instance_lbl,
Label* is_not_instance_lbl) {
- UNIMPLEMENTED();
- return NULL;
+ __ Comment("Subtype1TestCacheLookup");
+ const Register kInstanceReg = A0;
+ __ LoadClass(T0, kInstanceReg);
+ // T0: instance class.
+ // Check immediate superclass equality.
+ __ lw(T0, FieldAddress(T0, Class::super_type_offset()));
+ __ lw(T0, FieldAddress(T0, Type::type_class_offset()));
+ __ BranchEqual(T0, type_class, is_instance_lbl);
+
+ const Register kTypeArgumentsReg = kNoRegister;
+ const Register kTempReg = kNoRegister;
+ return GenerateCallSubtypeTestStub(kTestTypeOneArg,
+ kInstanceReg,
+ kTypeArgumentsReg,
+ kTempReg,
+ is_instance_lbl,
+ is_not_instance_lbl);
}
@@ -329,8 +379,8 @@
__ sw(A2, Address(SP, 1 * kWordSize));
__ sw(A1, Address(SP, 0 * kWordSize));
__ PushObject(dst_name); // Push the name of the destination.
- __ LoadObject(A0, test_cache);
- __ Push(A0);
+ __ LoadObject(T0, test_cache);
+ __ Push(T0);
GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
// Pop the parameters supplied to the runtime entry. The result of the
// type check runtime call is the checked value.
@@ -405,11 +455,11 @@
__ subu(T1, T1, T2);
__ sll(T1, T1, 1);
__ addu(T1, FP, T1);
- __ addiu(T1, T1, Immediate(kLastParamSlotIndex * kWordSize));
+ __ AddImmediate(T1, kLastParamSlotIndex * kWordSize);
// Let T0 point to the last copied positional argument, i.e. to
// fp[kFirstLocalSlotIndex - (num_pos_args - 1)].
- __ addiu(T0, FP, Immediate((kFirstLocalSlotIndex + 1) * kWordSize));
+ __ AddImmediate(T0, FP, (kFirstLocalSlotIndex + 1) * kWordSize);
__ sll(T3, T2, 1); // T2 is a Smi.
__ subu(T0, T0, T3);
@@ -457,10 +507,10 @@
// fp[kLastParamSlotIndex + num_args - 1 - 0]; num_args (T1) is Smi.
__ sll(T3, T1, 1);
__ addu(T1, FP, T3);
- __ addiu(T1, T1, Immediate((kLastParamSlotIndex - 1) * kWordSize));
+ __ AddImmediate(T1, (kLastParamSlotIndex - 1) * kWordSize);
// Let T0 point to the entry of the first named argument.
- __ addiu(T0, S4, Immediate(
- ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag));
+ __ AddImmediate(T0, S4,
+ ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag);
for (int i = 0; i < num_opt_named_params; i++) {
Label load_default_value, assign_optional_parameter;
const int param_pos = opt_param_position[i];
@@ -475,7 +525,7 @@
__ lw(T3, Address(T0, ArgumentsDescriptor::position_offset()));
// T3 is arg_pos as Smi.
// Point to next named entry.
- __ addiu(T0, T0, Immediate(ArgumentsDescriptor::named_entry_size()));
+ __ AddImmediate(T0, ArgumentsDescriptor::named_entry_size());
__ subu(T3, ZR, T3);
__ sll(T3, T3, 1);
__ addu(T3, T1, T3);
@@ -537,7 +587,7 @@
// We need to unwind the space we reserved for locals and copied parameters.
// The NoSuchMethodFunction stub does not expect to see that area on the
// stack.
- __ addiu(SP, SP, Immediate(StackSize() * kWordSize));
+ __ AddImmediate(SP, StackSize() * kWordSize);
}
// The call below has an empty stackmap because we have just
// dropped the spill slots.
@@ -730,7 +780,7 @@
// We need to unwind the space we reserved for locals and copied
// parameters. The NoSuchMethodFunction stub does not expect to see
// that area on the stack.
- __ addiu(SP, SP, Immediate(StackSize() * kWordSize));
+ __ AddImmediate(SP, StackSize() * kWordSize);
}
// The call below has an empty stackmap because we have just
// dropped the spill slots.
@@ -858,7 +908,22 @@
intptr_t deopt_id,
const RuntimeEntry& entry,
LocationSummary* locs) {
- __ Unimplemented("call runtime");
+ __ CallRuntime(entry);
+ AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
+ RecordSafepoint(locs);
+ if (deopt_id != Isolate::kNoDeoptId) {
+ // Marks either the continuation point in unoptimized code or the
+ // deoptimization point in optimized code, after call.
+ if (is_optimizing()) {
+ AddDeoptIndexAtCall(deopt_id, token_pos);
+ } else {
+ // Add deoptimization continuation point after the call and before the
+ // arguments are removed.
+ AddCurrentDescriptor(PcDescriptors::kDeoptAfter,
+ deopt_id,
+ token_pos);
+ }
+ }
}
@@ -932,7 +997,16 @@
void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
Register right,
bool needs_number_check) {
- UNIMPLEMENTED();
+ if (needs_number_check) {
+ __ Push(left);
+ __ Push(right);
+ __ BranchLink(&StubCode::IdenticalWithNumberCheckLabel());
+ // Stub returns result in CMPRES. If it is 0, then left and right are equal.
+ __ Pop(right);
+ __ Pop(left);
+ } else {
+ __ subu(CMPRES, left, right);
+ }
}
« no previous file with comments | « runtime/vm/constants_mips.h ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698