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

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 10450014: Request for comments on overall approach. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix scavenger and freelist handling 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 // A Smi object cannot be the instance of a parameterized class. 117 // A Smi object cannot be the instance of a parameterized class.
118 __ testq(RAX, Immediate(kSmiTagMask)); 118 __ testq(RAX, Immediate(kSmiTagMask));
119 __ j(ZERO, is_not_instance_lbl); 119 __ j(ZERO, is_not_instance_lbl);
120 const AbstractTypeArguments& type_arguments = 120 const AbstractTypeArguments& type_arguments =
121 AbstractTypeArguments::ZoneHandle(type.arguments()); 121 AbstractTypeArguments::ZoneHandle(type.arguments());
122 const bool is_raw_type = type_arguments.IsNull() || 122 const bool is_raw_type = type_arguments.IsNull() ||
123 type_arguments.IsRaw(type_arguments.Length()); 123 type_arguments.IsRaw(type_arguments.Length());
124 if (is_raw_type) { 124 if (is_raw_type) {
125 // Dynamic type argument, check only classes. 125 // Dynamic type argument, check only classes.
126 // List is a very common case. 126 // List is a very common case.
127 __ movq(R10, FieldAddress(RAX, Object::class_offset())); 127 __ GetClassOf(R10, RAX);
128 if (!type_class.is_interface()) { 128 if (!type_class.is_interface()) {
129 __ CompareObject(R10, type_class); 129 __ CompareObject(R10, type_class);
130 __ j(EQUAL, is_instance_lbl); 130 __ j(EQUAL, is_instance_lbl);
131 } 131 }
132 if (type.IsListInterface()) { 132 if (type.IsListInterface()) {
133 Label unknown; 133 Label unknown;
134 GrowableArray<const Class*> args; 134 GrowableArray<const Class*> args;
135 args.Add(CoreClass("ObjectArray")); 135 args.Add(CoreClass("ObjectArray"));
136 args.Add(CoreClass("GrowableObjectArray")); 136 args.Add(CoreClass("GrowableObjectArray"));
137 args.Add(CoreClass("ImmutableArray")); 137 args.Add(CoreClass("ImmutableArray"));
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 TypeArguments::Handle(), 225 TypeArguments::Handle(),
226 &malformed_error)) { 226 &malformed_error)) {
227 __ jmp(is_instance_lbl); 227 __ jmp(is_instance_lbl);
228 } else { 228 } else {
229 __ jmp(is_not_instance_lbl); 229 __ jmp(is_not_instance_lbl);
230 } 230 }
231 231
232 ObjectStore* object_store = Isolate::Current()->object_store(); 232 ObjectStore* object_store = Isolate::Current()->object_store();
233 // Compare if the classes are equal. Instance is not Smi. 233 // Compare if the classes are equal. Instance is not Smi.
234 __ Bind(&compare_classes); 234 __ Bind(&compare_classes);
235 __ movq(R10, FieldAddress(RAX, Object::class_offset())); 235 __ GetClassOf(R10, RAX);
236 // If type is an interface, we can skip the class equality check. 236 // If type is an interface, we can skip the class equality check.
237 if (!type_class.is_interface()) { 237 if (!type_class.is_interface()) {
238 __ CompareObject(R10, type_class); 238 __ CompareObject(R10, type_class);
239 __ j(EQUAL, is_instance_lbl); 239 __ j(EQUAL, is_instance_lbl);
240 } 240 }
241 // Check for interfaces that cannot be implemented by user. 241 // Check for interfaces that cannot be implemented by user.
242 // (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces). 242 // (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces).
243 // Bool interface can be implemented only by core class Bool. 243 // Bool interface can be implemented only by core class Bool.
244 if (type.IsBoolInterface()) { 244 if (type.IsBoolInterface()) {
245 const Class& bool_class = Class::ZoneHandle(object_store->bool_class()); 245 const Class& bool_class = Class::ZoneHandle(object_store->bool_class());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 intptr_t cid, 313 intptr_t cid,
314 intptr_t token_index, 314 intptr_t token_index,
315 const Class& type_class, 315 const Class& type_class,
316 Label* is_instance_lbl, 316 Label* is_instance_lbl,
317 Label* is_not_instance_lbl) { 317 Label* is_not_instance_lbl) {
318 const SubtypeTestCache& type_test_cache = 318 const SubtypeTestCache& type_test_cache =
319 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 319 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
320 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 320 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
321 const Immediate raw_null = 321 const Immediate raw_null =
322 Immediate(reinterpret_cast<intptr_t>(Object::null())); 322 Immediate(reinterpret_cast<intptr_t>(Object::null()));
323 __ movq(R10, FieldAddress(RAX, Object::class_offset())); 323 __ GetClassOf(R10, RAX);
324 // Check immediate superclass equality. 324 // Check immediate superclass equality.
325 __ movq(R13, FieldAddress(R10, Class::super_type_offset())); 325 __ movq(R13, FieldAddress(R10, Class::super_type_offset()));
326 __ movq(R13, FieldAddress(R13, Type::type_class_offset())); 326 __ movq(R13, FieldAddress(R13, Type::type_class_offset()));
327 __ CompareObject(R13, type_class); 327 __ CompareObject(R13, type_class);
328 __ j(EQUAL, is_instance_lbl); 328 __ j(EQUAL, is_instance_lbl);
329 329
330 __ LoadObject(R10, type_test_cache); 330 __ LoadObject(R10, type_test_cache);
331 __ pushq(R10); // Cache array. 331 __ pushq(R10); // Cache array.
332 __ pushq(RAX); // Instance. 332 __ pushq(RAX); // Instance.
333 __ pushq(raw_null); // Unused 333 __ pushq(raw_null); // Unused
(...skipping 28 matching lines...) Expand all
362 if (type.IsTypeParameter()) { 362 if (type.IsTypeParameter()) {
363 // Load instantiator (or null) and instantiator type arguments on stack. 363 // Load instantiator (or null) and instantiator type arguments on stack.
364 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. 364 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments.
365 // RDX: instantiator type arguments. 365 // RDX: instantiator type arguments.
366 // Check if type argument is Dynamic. 366 // Check if type argument is Dynamic.
367 __ cmpq(RDX, raw_null); 367 __ cmpq(RDX, raw_null);
368 __ j(EQUAL, is_instance_lbl); 368 __ j(EQUAL, is_instance_lbl);
369 // Can handle only type arguments that are instances of TypeArguments. 369 // Can handle only type arguments that are instances of TypeArguments.
370 // (runtime checks canonicalize type arguments). 370 // (runtime checks canonicalize type arguments).
371 Label fall_through; 371 Label fall_through;
372 __ movq(R10, FieldAddress(RDX, Object::class_offset())); 372 __ GetClassOf(R10, RDX);
373 __ CompareObject(R10, Object::ZoneHandle(Object::type_arguments_class())); 373 __ CompareObject(R10, Object::ZoneHandle(Object::type_arguments_class()));
374 __ j(NOT_EQUAL, &fall_through); 374 __ j(NOT_EQUAL, &fall_through);
375 __ movq(RDI, 375 __ movq(RDI,
376 FieldAddress(RDX, TypeArguments::type_at_offset(type.Index()))); 376 FieldAddress(RDX, TypeArguments::type_at_offset(type.Index())));
377 // RDI: Concrete type. 377 // RDI: Concrete type.
378 // Check if it is Dynamic, 378 // Check if it is Dynamic,
379 __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType())); 379 __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType()));
380 __ j(EQUAL, is_instance_lbl); 380 __ j(EQUAL, is_instance_lbl);
381 __ cmpq(RDI, raw_null); 381 __ cmpq(RDI, raw_null);
382 __ j(EQUAL, is_instance_lbl); 382 __ j(EQUAL, is_instance_lbl);
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 __ cmpq(RAX, raw_null); 1138 __ cmpq(RAX, raw_null);
1139 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1139 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1140 } 1140 }
1141 // Instantiate non-null type arguments. 1141 // Instantiate non-null type arguments.
1142 if (comp->type_arguments().IsUninstantiatedIdentity()) { 1142 if (comp->type_arguments().IsUninstantiatedIdentity()) {
1143 Label type_arguments_uninstantiated; 1143 Label type_arguments_uninstantiated;
1144 // Check if the instantiator type argument vector is a TypeArguments of a 1144 // Check if the instantiator type argument vector is a TypeArguments of a
1145 // matching length and, if so, use it as the instantiated type_arguments. 1145 // matching length and, if so, use it as the instantiated type_arguments.
1146 // No need to check the instantiator (RAX) for null here, because a null 1146 // No need to check the instantiator (RAX) for null here, because a null
1147 // instantiator will have the wrong class (Null instead of TypeArguments). 1147 // instantiator will have the wrong class (Null instead of TypeArguments).
1148 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 1148 __ GetClassOf(R10, RAX);
1149 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 1149 __ CompareObject(R10, Class::ZoneHandle(Object::type_arguments_class()));
1150 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1150 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1151 Immediate arguments_length = 1151 Immediate arguments_length =
1152 Immediate(Smi::RawValue(comp->type_arguments().Length())); 1152 Immediate(Smi::RawValue(comp->type_arguments().Length()));
1153 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 1153 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
1154 arguments_length); 1154 arguments_length);
1155 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1155 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1156 __ Bind(&type_arguments_uninstantiated); 1156 __ Bind(&type_arguments_uninstantiated);
1157 } 1157 }
1158 // A runtime call to instantiate the type arguments is required. 1158 // A runtime call to instantiate the type arguments is required.
1159 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1159 __ PushObject(Object::ZoneHandle()); // Make room for the result.
(...skipping 27 matching lines...) Expand all
1187 __ cmpq(RAX, raw_null); 1187 __ cmpq(RAX, raw_null);
1188 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1188 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1189 } 1189 }
1190 // Instantiate non-null type arguments. 1190 // Instantiate non-null type arguments.
1191 if (comp->type_arguments().IsUninstantiatedIdentity()) { 1191 if (comp->type_arguments().IsUninstantiatedIdentity()) {
1192 // Check if the instantiator type argument vector is a TypeArguments of a 1192 // Check if the instantiator type argument vector is a TypeArguments of a
1193 // matching length and, if so, use it as the instantiated type_arguments. 1193 // matching length and, if so, use it as the instantiated type_arguments.
1194 // No need to check the instantiator (RAX) for null here, because a null 1194 // No need to check the instantiator (RAX) for null here, because a null
1195 // instantiator will have the wrong class (Null instead of TypeArguments). 1195 // instantiator will have the wrong class (Null instead of TypeArguments).
1196 Label type_arguments_uninstantiated; 1196 Label type_arguments_uninstantiated;
1197 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 1197 __ GetClassOf(R10, RAX);
1198 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 1198 __ CompareObject(R10, Class::ZoneHandle(Object::type_arguments_class()));
1199 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1199 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1200 Immediate arguments_length = 1200 Immediate arguments_length =
1201 Immediate(Smi::RawValue(comp->type_arguments().Length())); 1201 Immediate(Smi::RawValue(comp->type_arguments().Length()));
1202 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 1202 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
1203 arguments_length); 1203 arguments_length);
1204 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1204 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1205 __ Bind(&type_arguments_uninstantiated); 1205 __ Bind(&type_arguments_uninstantiated);
1206 } 1206 }
1207 // In the non-factory case, we rely on the allocation stub to 1207 // In the non-factory case, we rely on the allocation stub to
1208 // instantiate the type arguments. 1208 // instantiate the type arguments.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 // TODO(regis): The following emitted code is duplicated in 1241 // TODO(regis): The following emitted code is duplicated in
1242 // VisitExtractConstructorTypeArguments above. The reason is that the code 1242 // VisitExtractConstructorTypeArguments above. The reason is that the code
1243 // is split between two computations, so that each one produces a 1243 // is split between two computations, so that each one produces a
1244 // single value, rather than producing a pair of values. 1244 // single value, rather than producing a pair of values.
1245 // If this becomes an issue, we should expose these tests at the IL level. 1245 // If this becomes an issue, we should expose these tests at the IL level.
1246 1246
1247 // Check if the instantiator type argument vector is a TypeArguments of a 1247 // Check if the instantiator type argument vector is a TypeArguments of a
1248 // matching length and, if so, use it as the instantiated type_arguments. 1248 // matching length and, if so, use it as the instantiated type_arguments.
1249 // No need to check the instantiator (RAX) for null here, because a null 1249 // No need to check the instantiator (RAX) for null here, because a null
1250 // instantiator will have the wrong class (Null instead of TypeArguments). 1250 // instantiator will have the wrong class (Null instead of TypeArguments).
1251 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 1251 __ GetClassOf(R10, RAX);
1252 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 1252 __ CompareObject(R10, Class::ZoneHandle(Object::type_arguments_class()));
1253 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1253 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1254 Immediate arguments_length = 1254 Immediate arguments_length =
1255 Immediate(Smi::RawValue(comp->type_arguments().Length())); 1255 Immediate(Smi::RawValue(comp->type_arguments().Length()));
1256 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 1256 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
1257 arguments_length); 1257 arguments_length);
1258 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1258 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1259 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1259 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1260 // instantiated type arguments, no proper instantiator needed. 1260 // instantiated type arguments, no proper instantiator needed.
1261 __ movq(RAX, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1261 __ movq(RAX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1262 } 1262 }
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1931 1931
1932 1932
1933 void FlowGraphCompiler::FinalizeComments(const Code& code) { 1933 void FlowGraphCompiler::FinalizeComments(const Code& code) {
1934 code.set_comments(assembler_->GetCodeComments()); 1934 code.set_comments(assembler_->GetCodeComments());
1935 } 1935 }
1936 1936
1937 1937
1938 } // namespace dart 1938 } // namespace dart
1939 1939
1940 #endif // defined TARGET_ARCH_X64 1940 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698