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

Unified Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 10407018: Start porting fast typechecks to x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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
Index: runtime/vm/flow_graph_compiler_x64.cc
===================================================================
--- runtime/vm/flow_graph_compiler_x64.cc (revision 7716)
+++ runtime/vm/flow_graph_compiler_x64.cc (working copy)
@@ -106,9 +106,12 @@
// Note that this inlined code must be followed by the runtime_call code, as it
// may fall through to it. Otherwise, this inline code will jump to the label
// is_instance or to the label is_not_instance.
-void FlowGraphCompiler::GenerateInlineInstanceof(const AbstractType& type,
- Label* is_instance,
- Label* is_not_instance) {
+RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
+ intptr_t cid,
+ intptr_t token_index,
+ const AbstractType& type,
+ Label* is_instance,
+ Label* is_not_instance) {
Label runtime_call;
if (type.IsInstantiated()) {
const Class& type_class = Class::ZoneHandle(type.type_class());
@@ -269,6 +272,7 @@
}
}
__ Bind(&runtime_call);
+ return SubtypeTestCache::null();
}
@@ -278,7 +282,8 @@
// - Class equality (only if class is not parameterized).
// Inputs:
// - RAX: object.
-// - RDX: optional instantiator type arguments.
+// - RDX: instantiator type arguments or raw_null.
+// - RCX: instantiator or raw_null.
// Destroys RCX and RDX.
// Returns:
// - object in RAX for successful assignable check (or throws TypeError).
@@ -293,10 +298,11 @@
ASSERT(token_index >= 0);
ASSERT(!dst_type.IsNull());
ASSERT(dst_type.IsFinalized());
+ // Assignable check is skipped in FlowGraphBuilder, not here.
ASSERT(dst_type.IsMalformed() ||
(!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
ASSERT(!dst_type.IsVoidType());
-
+ __ pushq(RCX); // Temporary store instantiator on stack.
// A null object is always assignable and is returned as result.
const Immediate raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -326,22 +332,21 @@
}
// Generate inline type check, linking to runtime call if not assignable.
- GenerateInlineInstanceof(dst_type, &is_assignable, &runtime_call);
-
+ SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
+ test_cache = GenerateInlineInstanceof(cid, token_index, dst_type,
+ &is_assignable, &runtime_call);
__ Bind(&runtime_call);
+ __ movq(RCX, Address(RSP, 0)); // Get instantiator.
__ PushObject(Object::ZoneHandle()); // Make room for the result.
__ pushq(Immediate(Smi::RawValue(token_index))); // Source location.
__ pushq(Immediate(Smi::RawValue(cid))); // Computation id.
__ pushq(RAX); // Push the source object.
__ PushObject(dst_type); // Push the type of the destination.
- __ pushq(raw_null); // TODO(srdjan): Instantiator.
- if (dst_type.IsInstantiated()) {
- __ pushq(raw_null); // Null instantiator type arguments.
- } else {
- __ pushq(RDX); // Instantiator type arguments.
- }
+ __ pushq(RCX); // Instantiator.
+ __ pushq(RDX); // Instantiator type arguments.
__ PushObject(dst_name); // Push the name of the destination.
- __ pushq(raw_null); // SubtypeTestCache not yet supported.
+ __ LoadObject(RAX, test_cache);
+ __ pushq(RAX);
GenerateCallRuntime(cid,
token_index,
try_index,
@@ -352,6 +357,7 @@
__ popq(RAX);
__ Bind(&is_assignable);
+ __ popq(RCX); // Remove pushed instantiator.
}
@@ -382,9 +388,18 @@
void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) {
- if (comp->instantiator_type_arguments() != NULL) {
- __ popq(RDX);
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ if (comp->instantiator_type_arguments() == NULL) {
+ __ movq(RDX, raw_null);
+ } else {
+ LoadValue(RDX, comp->instantiator_type_arguments());
}
+ if (comp->instantiator() == NULL) {
+ __ movq(RCX, raw_null);
+ } else {
+ LoadValue(RCX, comp->instantiator());
+ }
LoadValue(RAX, comp->value());
GenerateAssertAssignable(comp->cid(),
comp->token_index(),
@@ -754,7 +769,8 @@
// - Class equality (only if class is not parameterized).
// Inputs:
// - RAX: object.
-// - RDX: optional instantiator type arguments.
+// - RDX: oinstantiator type arguments or raw_null.
+// - RCX: instantiator or raw_null.
// Destroys RCX and RDX.
// Returns:
// - true or false in RAX.
@@ -770,6 +786,7 @@
const Immediate raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label is_instance, is_not_instance;
+ __ pushq(RCX); // Temporary store instantiator on stack.
// If type is instantiated and non-parameterized, we can inline code
// checking whether the tested instance is a Smi.
if (type.IsInstantiated()) {
@@ -785,7 +802,9 @@
}
// Generate inline instanceof test.
- GenerateInlineInstanceof(type, &is_instance, &is_not_instance);
+ SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
+ test_cache = GenerateInlineInstanceof(cid, token_index, type,
+ &is_instance, &is_not_instance);
// Generate runtime call.
__ PushObject(Object::ZoneHandle()); // Make room for the result.
@@ -823,13 +842,23 @@
__ Bind(&is_instance);
__ LoadObject(RAX, negate_result ? bool_false : bool_true);
__ Bind(&done);
+ __ popq(RCX); // Remove pushed instantiator.
}
void FlowGraphCompiler::VisitInstanceOf(InstanceOfComp* comp) {
- if (comp->type_arguments() != NULL) {
- __ popq(RDX);
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ if (comp->type_arguments() == NULL) {
+ __ movq(RDX, raw_null);
+ } else {
+ LoadValue(RDX, comp->type_arguments());
}
+ if (comp->instantiator() == NULL) {
+ __ movq(RCX, raw_null);
+ } else {
+ LoadValue(RCX, comp->instantiator());
+ }
LoadValue(RAX, comp->value());
GenerateInstanceOf(comp->cid(),
comp->token_index(),

Powered by Google App Engine
This is Rietveld 408576698