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

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

Issue 1263573010: Use zone when allocating handles in FlowGraphCompiler assembling operations. Add profiling VM tags… (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: sync Created 5 years, 4 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
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/flow_graph_compiler_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 intptr_t slot_ix = 0; 91 intptr_t slot_ix = 0;
92 Environment* current = deopt_env_; 92 Environment* current = deopt_env_;
93 93
94 // Emit all kMaterializeObject instructions describing objects to be 94 // Emit all kMaterializeObject instructions describing objects to be
95 // materialized on the deoptimization as a prefix to the deoptimization info. 95 // materialized on the deoptimization as a prefix to the deoptimization info.
96 EmitMaterializations(deopt_env_, builder); 96 EmitMaterializations(deopt_env_, builder);
97 97
98 // The real frame starts here. 98 // The real frame starts here.
99 builder->MarkFrameStart(); 99 builder->MarkFrameStart();
100 100
101 Zone* zone = compiler->zone();
102
101 // Current PP, FP, and PC. 103 // Current PP, FP, and PC.
102 builder->AddPp(Function::Handle(current->code().function()), slot_ix++); 104 builder->AddPp(Function::Handle(zone, current->code().function()), slot_ix++);
103 builder->AddCallerFp(slot_ix++); 105 builder->AddCallerFp(slot_ix++);
104 builder->AddReturnAddress(Function::Handle(current->code().function()), 106 builder->AddReturnAddress(Function::Handle(zone, current->code().function()),
105 deopt_id(), 107 deopt_id(),
106 slot_ix++); 108 slot_ix++);
107 109
108 // Callee's PC marker is not used anymore. Pass Function::null() to set to 0. 110 // Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
109 builder->AddPcMarker(Function::Handle(), slot_ix++); 111 builder->AddPcMarker(Function::Handle(zone), slot_ix++);
110 112
111 // Emit all values that are needed for materialization as a part of the 113 // Emit all values that are needed for materialization as a part of the
112 // expression stack for the bottom-most frame. This guarantees that GC 114 // expression stack for the bottom-most frame. This guarantees that GC
113 // will be able to find them during materialization. 115 // will be able to find them during materialization.
114 slot_ix = builder->EmitMaterializationArguments(slot_ix); 116 slot_ix = builder->EmitMaterializationArguments(slot_ix);
115 117
116 // For the innermost environment, set outgoing arguments and the locals. 118 // For the innermost environment, set outgoing arguments and the locals.
117 for (intptr_t i = current->Length() - 1; 119 for (intptr_t i = current->Length() - 1;
118 i >= current->fixed_parameter_count(); 120 i >= current->fixed_parameter_count();
119 i--) { 121 i--) {
120 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); 122 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
121 } 123 }
122 124
123 Environment* previous = current; 125 Environment* previous = current;
124 current = current->outer(); 126 current = current->outer();
125 while (current != NULL) { 127 while (current != NULL) {
126 // PP, FP, and PC. 128 // PP, FP, and PC.
127 builder->AddPp(Function::Handle(current->code().function()), slot_ix++); 129 builder->AddPp(
130 Function::Handle(zone, current->code().function()), slot_ix++);
128 builder->AddCallerFp(slot_ix++); 131 builder->AddCallerFp(slot_ix++);
129 132
130 // For any outer environment the deopt id is that of the call instruction 133 // For any outer environment the deopt id is that of the call instruction
131 // which is recorded in the outer environment. 134 // which is recorded in the outer environment.
132 builder->AddReturnAddress(Function::Handle(current->code().function()), 135 builder->AddReturnAddress(
133 Isolate::ToDeoptAfter(current->deopt_id()), 136 Function::Handle(zone, current->code().function()),
134 slot_ix++); 137 Isolate::ToDeoptAfter(current->deopt_id()),
138 slot_ix++);
135 139
136 // PC marker. 140 // PC marker.
137 builder->AddPcMarker(Function::Handle(previous->code().function()), 141 builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
138 slot_ix++); 142 slot_ix++);
139 143
140 // The values of outgoing arguments can be changed from the inlined call so 144 // The values of outgoing arguments can be changed from the inlined call so
141 // we must read them from the previous environment. 145 // we must read them from the previous environment.
142 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 146 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
143 builder->AddCopy(previous->ValueAt(i), 147 builder->AddCopy(previous->ValueAt(i),
144 previous->LocationAt(i), 148 previous->LocationAt(i),
145 slot_ix++); 149 slot_ix++);
146 } 150 }
147 151
(...skipping 12 matching lines...) Expand all
160 } 164 }
161 // The previous pointer is now the outermost environment. 165 // The previous pointer is now the outermost environment.
162 ASSERT(previous != NULL); 166 ASSERT(previous != NULL);
163 167
164 // For the outermost environment, set caller PC, caller PP, and caller FP. 168 // For the outermost environment, set caller PC, caller PP, and caller FP.
165 builder->AddCallerPp(slot_ix++); 169 builder->AddCallerPp(slot_ix++);
166 builder->AddCallerFp(slot_ix++); 170 builder->AddCallerFp(slot_ix++);
167 builder->AddCallerPc(slot_ix++); 171 builder->AddCallerPc(slot_ix++);
168 172
169 // PC marker. 173 // PC marker.
170 builder->AddPcMarker(Function::Handle(previous->code().function()), 174 builder->AddPcMarker(Function::Handle(zone, previous->code().function()),
171 slot_ix++); 175 slot_ix++);
172 176
173 // For the outermost environment, set the incoming arguments. 177 // For the outermost environment, set the incoming arguments.
174 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 178 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
175 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); 179 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
176 } 180 }
177 181
178 return builder->CreateDeoptInfo(deopt_table); 182 return builder->CreateDeoptInfo(deopt_table);
179 } 183 }
180 184
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( 230 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
227 TypeTestStubKind test_kind, 231 TypeTestStubKind test_kind,
228 Register instance_reg, 232 Register instance_reg,
229 Register type_arguments_reg, 233 Register type_arguments_reg,
230 Register temp_reg, 234 Register temp_reg,
231 Label* is_instance_lbl, 235 Label* is_instance_lbl,
232 Label* is_not_instance_lbl) { 236 Label* is_not_instance_lbl) {
233 ASSERT(instance_reg == R0); 237 ASSERT(instance_reg == R0);
234 ASSERT(temp_reg == kNoRegister); // Unused on ARM. 238 ASSERT(temp_reg == kNoRegister); // Unused on ARM.
235 const SubtypeTestCache& type_test_cache = 239 const SubtypeTestCache& type_test_cache =
236 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 240 SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
237 __ LoadUniqueObject(R2, type_test_cache); 241 __ LoadUniqueObject(R2, type_test_cache);
238 if (test_kind == kTestTypeOneArg) { 242 if (test_kind == kTestTypeOneArg) {
239 ASSERT(type_arguments_reg == kNoRegister); 243 ASSERT(type_arguments_reg == kNoRegister);
240 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); 244 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
241 __ BranchLink(&StubCode::Subtype1TestCacheLabel()); 245 __ BranchLink(&StubCode::Subtype1TestCacheLabel());
242 } else if (test_kind == kTestTypeTwoArgs) { 246 } else if (test_kind == kTestTypeTwoArgs) {
243 ASSERT(type_arguments_reg == kNoRegister); 247 ASSERT(type_arguments_reg == kNoRegister);
244 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); 248 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
245 __ BranchLink(&StubCode::Subtype2TestCacheLabel()); 249 __ BranchLink(&StubCode::Subtype2TestCacheLabel());
246 } else if (test_kind == kTestTypeThreeArgs) { 250 } else if (test_kind == kTestTypeThreeArgs) {
(...skipping 14 matching lines...) Expand all
261 // R0: instance being type checked (preserved). 265 // R0: instance being type checked (preserved).
262 // Clobbers R2. 266 // Clobbers R2.
263 RawSubtypeTestCache* 267 RawSubtypeTestCache*
264 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( 268 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
265 intptr_t token_pos, 269 intptr_t token_pos,
266 const AbstractType& type, 270 const AbstractType& type,
267 Label* is_instance_lbl, 271 Label* is_instance_lbl,
268 Label* is_not_instance_lbl) { 272 Label* is_not_instance_lbl) {
269 __ Comment("InstantiatedTypeWithArgumentsTest"); 273 __ Comment("InstantiatedTypeWithArgumentsTest");
270 ASSERT(type.IsInstantiated()); 274 ASSERT(type.IsInstantiated());
271 const Class& type_class = Class::ZoneHandle(type.type_class()); 275 const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
272 ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass()); 276 ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
273 const Register kInstanceReg = R0; 277 const Register kInstanceReg = R0;
274 Error& malformed_error = Error::Handle(); 278 Error& malformed_error = Error::Handle(zone());
275 const Type& int_type = Type::Handle(Type::IntType()); 279 const Type& int_type = Type::Handle(zone(), Type::IntType());
276 const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error); 280 const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
277 // Malformed type should have been handled at graph construction time. 281 // Malformed type should have been handled at graph construction time.
278 ASSERT(smi_is_ok || malformed_error.IsNull()); 282 ASSERT(smi_is_ok || malformed_error.IsNull());
279 __ tst(kInstanceReg, Operand(kSmiTagMask)); 283 __ tst(kInstanceReg, Operand(kSmiTagMask));
280 if (smi_is_ok) { 284 if (smi_is_ok) {
281 __ b(is_instance_lbl, EQ); 285 __ b(is_instance_lbl, EQ);
282 } else { 286 } else {
283 __ b(is_not_instance_lbl, EQ); 287 __ b(is_not_instance_lbl, EQ);
284 } 288 }
285 const intptr_t num_type_args = type_class.NumTypeArguments(); 289 const intptr_t num_type_args = type_class.NumTypeArguments();
286 const intptr_t num_type_params = type_class.NumTypeParameters(); 290 const intptr_t num_type_params = type_class.NumTypeParameters();
287 const intptr_t from_index = num_type_args - num_type_params; 291 const intptr_t from_index = num_type_args - num_type_params;
288 const TypeArguments& type_arguments = 292 const TypeArguments& type_arguments =
289 TypeArguments::ZoneHandle(type.arguments()); 293 TypeArguments::ZoneHandle(zone(), type.arguments());
290 const bool is_raw_type = type_arguments.IsNull() || 294 const bool is_raw_type = type_arguments.IsNull() ||
291 type_arguments.IsRaw(from_index, num_type_params); 295 type_arguments.IsRaw(from_index, num_type_params);
292 // Signature class is an instantiated parameterized type. 296 // Signature class is an instantiated parameterized type.
293 if (!type_class.IsSignatureClass()) { 297 if (!type_class.IsSignatureClass()) {
294 if (is_raw_type) { 298 if (is_raw_type) {
295 const Register kClassIdReg = R2; 299 const Register kClassIdReg = R2;
296 // dynamic type argument, check only classes. 300 // dynamic type argument, check only classes.
297 __ LoadClassId(kClassIdReg, kInstanceReg); 301 __ LoadClassId(kClassIdReg, kInstanceReg);
298 __ CompareImmediate(kClassIdReg, type_class.id()); 302 __ CompareImmediate(kClassIdReg, type_class.id());
299 __ b(is_instance_lbl, EQ); 303 __ b(is_instance_lbl, EQ);
300 // List is a very common case. 304 // List is a very common case.
301 if (IsListClass(type_class)) { 305 if (IsListClass(type_class)) {
302 GenerateListTypeCheck(kClassIdReg, is_instance_lbl); 306 GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
303 } 307 }
304 return GenerateSubtype1TestCacheLookup( 308 return GenerateSubtype1TestCacheLookup(
305 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); 309 token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
306 } 310 }
307 // If one type argument only, check if type argument is Object or dynamic. 311 // If one type argument only, check if type argument is Object or dynamic.
308 if (type_arguments.Length() == 1) { 312 if (type_arguments.Length() == 1) {
309 const AbstractType& tp_argument = AbstractType::ZoneHandle( 313 const AbstractType& tp_argument = AbstractType::ZoneHandle(
310 type_arguments.TypeAt(0)); 314 zone(), type_arguments.TypeAt(0));
311 ASSERT(!tp_argument.IsMalformed()); 315 ASSERT(!tp_argument.IsMalformed());
312 if (tp_argument.IsType()) { 316 if (tp_argument.IsType()) {
313 ASSERT(tp_argument.HasResolvedTypeClass()); 317 ASSERT(tp_argument.HasResolvedTypeClass());
314 // Check if type argument is dynamic or Object. 318 // Check if type argument is dynamic or Object.
315 const Type& object_type = Type::Handle(Type::ObjectType()); 319 const Type& object_type = Type::Handle(zone(), Type::ObjectType());
316 if (object_type.IsSubtypeOf(tp_argument, NULL)) { 320 if (object_type.IsSubtypeOf(tp_argument, NULL)) {
317 // Instance class test only necessary. 321 // Instance class test only necessary.
318 return GenerateSubtype1TestCacheLookup( 322 return GenerateSubtype1TestCacheLookup(
319 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); 323 token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
320 } 324 }
321 } 325 }
322 } 326 }
323 } 327 }
324 // Regular subtype test cache involving instance's type arguments. 328 // Regular subtype test cache involving instance's type arguments.
325 const Register kTypeArgumentsReg = kNoRegister; 329 const Register kTypeArgumentsReg = kNoRegister;
(...skipping 25 matching lines...) Expand all
351 // R0: instance being type checked (preserved). 355 // R0: instance being type checked (preserved).
352 // Clobbers R2, R3. 356 // Clobbers R2, R3.
353 // Returns true if there is a fallthrough. 357 // Returns true if there is a fallthrough.
354 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( 358 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
355 intptr_t token_pos, 359 intptr_t token_pos,
356 const AbstractType& type, 360 const AbstractType& type,
357 Label* is_instance_lbl, 361 Label* is_instance_lbl,
358 Label* is_not_instance_lbl) { 362 Label* is_not_instance_lbl) {
359 __ Comment("InstantiatedTypeNoArgumentsTest"); 363 __ Comment("InstantiatedTypeNoArgumentsTest");
360 ASSERT(type.IsInstantiated()); 364 ASSERT(type.IsInstantiated());
361 const Class& type_class = Class::Handle(type.type_class()); 365 const Class& type_class = Class::Handle(zone(), type.type_class());
362 ASSERT(type_class.NumTypeArguments() == 0); 366 ASSERT(type_class.NumTypeArguments() == 0);
363 367
364 const Register kInstanceReg = R0; 368 const Register kInstanceReg = R0;
365 __ tst(kInstanceReg, Operand(kSmiTagMask)); 369 __ tst(kInstanceReg, Operand(kSmiTagMask));
366 // If instance is Smi, check directly. 370 // If instance is Smi, check directly.
367 const Class& smi_class = Class::Handle(Smi::Class()); 371 const Class& smi_class = Class::Handle(zone(), Smi::Class());
368 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), 372 if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
369 type_class, 373 type_class,
370 TypeArguments::Handle(), 374 TypeArguments::Handle(zone()),
371 NULL)) { 375 NULL)) {
372 __ b(is_instance_lbl, EQ); 376 __ b(is_instance_lbl, EQ);
373 } else { 377 } else {
374 __ b(is_not_instance_lbl, EQ); 378 __ b(is_not_instance_lbl, EQ);
375 } 379 }
376 // Compare if the classes are equal. 380 // Compare if the classes are equal.
377 const Register kClassIdReg = R2; 381 const Register kClassIdReg = R2;
378 __ LoadClassId(kClassIdReg, kInstanceReg); 382 __ LoadClassId(kClassIdReg, kInstanceReg);
379 __ CompareImmediate(kClassIdReg, type_class.id()); 383 __ CompareImmediate(kClassIdReg, type_class.id());
380 __ b(is_instance_lbl, EQ); 384 __ b(is_instance_lbl, EQ);
381 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted 385 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted
382 // interfaces. 386 // interfaces.
383 // Bool interface can be implemented only by core class Bool. 387 // Bool interface can be implemented only by core class Bool.
384 if (type.IsBoolType()) { 388 if (type.IsBoolType()) {
385 __ CompareImmediate(kClassIdReg, kBoolCid); 389 __ CompareImmediate(kClassIdReg, kBoolCid);
386 __ b(is_instance_lbl, EQ); 390 __ b(is_instance_lbl, EQ);
387 __ b(is_not_instance_lbl); 391 __ b(is_not_instance_lbl);
388 return false; 392 return false;
389 } 393 }
390 if (type.IsFunctionType()) { 394 if (type.IsFunctionType()) {
391 // Check if instance is a closure. 395 // Check if instance is a closure.
392 __ LoadClassById(R3, kClassIdReg); 396 __ LoadClassById(R3, kClassIdReg);
393 __ ldr(R3, FieldAddress(R3, Class::signature_function_offset())); 397 __ ldr(R3, FieldAddress(R3, Class::signature_function_offset()));
394 __ CompareImmediate(R3, reinterpret_cast<int32_t>(Object::null())); 398 __ CompareImmediate(R3, reinterpret_cast<int32_t>(Object::null()));
395 __ b(is_instance_lbl, NE); 399 __ b(is_instance_lbl, NE);
396 } 400 }
397 // Custom checking for numbers (Smi, Mint, Bigint and Double). 401 // Custom checking for numbers (Smi, Mint, Bigint and Double).
398 // Note that instance is not Smi (checked above). 402 // Note that instance is not Smi (checked above).
399 if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) { 403 if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) {
400 GenerateNumberTypeCheck( 404 GenerateNumberTypeCheck(
401 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl); 405 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
402 return false; 406 return false;
403 } 407 }
404 if (type.IsStringType()) { 408 if (type.IsStringType()) {
405 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); 409 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
406 return false; 410 return false;
407 } 411 }
408 // Otherwise fallthrough. 412 // Otherwise fallthrough.
409 return true; 413 return true;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 // Load instantiator (or null) and instantiator type arguments on stack. 462 // Load instantiator (or null) and instantiator type arguments on stack.
459 __ ldr(R1, Address(SP, 0)); // Get instantiator type arguments. 463 __ ldr(R1, Address(SP, 0)); // Get instantiator type arguments.
460 // R1: instantiator type arguments. 464 // R1: instantiator type arguments.
461 // Check if type arguments are null, i.e. equivalent to vector of dynamic. 465 // Check if type arguments are null, i.e. equivalent to vector of dynamic.
462 __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); 466 __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
463 __ b(is_instance_lbl, EQ); 467 __ b(is_instance_lbl, EQ);
464 __ ldr(R2, 468 __ ldr(R2,
465 FieldAddress(R1, TypeArguments::type_at_offset(type_param.index()))); 469 FieldAddress(R1, TypeArguments::type_at_offset(type_param.index())));
466 // R2: concrete type of type. 470 // R2: concrete type of type.
467 // Check if type argument is dynamic. 471 // Check if type argument is dynamic.
468 __ CompareObject(R2, Type::ZoneHandle(Type::DynamicType())); 472 __ CompareObject(R2, Type::ZoneHandle(zone(), Type::DynamicType()));
469 __ b(is_instance_lbl, EQ); 473 __ b(is_instance_lbl, EQ);
470 __ CompareObject(R2, Type::ZoneHandle(Type::ObjectType())); 474 __ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
471 __ b(is_instance_lbl, EQ); 475 __ b(is_instance_lbl, EQ);
472 476
473 // For Smi check quickly against int and num interfaces. 477 // For Smi check quickly against int and num interfaces.
474 Label not_smi; 478 Label not_smi;
475 __ tst(R0, Operand(kSmiTagMask)); // Value is Smi? 479 __ tst(R0, Operand(kSmiTagMask)); // Value is Smi?
476 __ b(&not_smi, NE); 480 __ b(&not_smi, NE);
477 __ CompareObject(R2, Type::ZoneHandle(Type::IntType())); 481 __ CompareObject(R2, Type::ZoneHandle(zone(), Type::IntType()));
478 __ b(is_instance_lbl, EQ); 482 __ b(is_instance_lbl, EQ);
479 __ CompareObject(R2, Type::ZoneHandle(Type::Number())); 483 __ CompareObject(R2, Type::ZoneHandle(zone(), Type::Number()));
480 __ b(is_instance_lbl, EQ); 484 __ b(is_instance_lbl, EQ);
481 // Smi must be handled in runtime. 485 // Smi must be handled in runtime.
482 Label fall_through; 486 Label fall_through;
483 __ b(&fall_through); 487 __ b(&fall_through);
484 488
485 __ Bind(&not_smi); 489 __ Bind(&not_smi);
486 // R1: instantiator type arguments. 490 // R1: instantiator type arguments.
487 // R0: instance. 491 // R0: instance.
488 const Register kInstanceReg = R0; 492 const Register kInstanceReg = R0;
489 const Register kTypeArgumentsReg = R1; 493 const Register kTypeArgumentsReg = R1;
490 const Register kTempReg = kNoRegister; 494 const Register kTempReg = kNoRegister;
491 const SubtypeTestCache& type_test_cache = 495 const SubtypeTestCache& type_test_cache =
492 SubtypeTestCache::ZoneHandle( 496 SubtypeTestCache::ZoneHandle(zone(),
493 GenerateCallSubtypeTestStub(kTestTypeThreeArgs, 497 GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
494 kInstanceReg, 498 kInstanceReg,
495 kTypeArgumentsReg, 499 kTypeArgumentsReg,
496 kTempReg, 500 kTempReg,
497 is_instance_lbl, 501 is_instance_lbl,
498 is_not_instance_lbl)); 502 is_not_instance_lbl));
499 __ Bind(&fall_through); 503 __ Bind(&fall_through);
500 return type_test_cache.raw(); 504 return type_test_cache.raw();
501 } 505 }
502 if (type.IsType()) { 506 if (type.IsType()) {
(...skipping 30 matching lines...) Expand all
533 const AbstractType& type, 537 const AbstractType& type,
534 Label* is_instance_lbl, 538 Label* is_instance_lbl,
535 Label* is_not_instance_lbl) { 539 Label* is_not_instance_lbl) {
536 __ Comment("InlineInstanceof"); 540 __ Comment("InlineInstanceof");
537 if (type.IsVoidType()) { 541 if (type.IsVoidType()) {
538 // A non-null value is returned from a void function, which will result in a 542 // A non-null value is returned from a void function, which will result in a
539 // type error. A null value is handled prior to executing this inline code. 543 // type error. A null value is handled prior to executing this inline code.
540 return SubtypeTestCache::null(); 544 return SubtypeTestCache::null();
541 } 545 }
542 if (type.IsInstantiated()) { 546 if (type.IsInstantiated()) {
543 const Class& type_class = Class::ZoneHandle(type.type_class()); 547 const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
544 // A class equality check is only applicable with a dst type of a 548 // A class equality check is only applicable with a dst type of a
545 // non-parameterized class, non-signature class, or with a raw dst type of 549 // non-parameterized class, non-signature class, or with a raw dst type of
546 // a parameterized class. 550 // a parameterized class.
547 if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) { 551 if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) {
548 return GenerateInstantiatedTypeWithArgumentsTest(token_pos, 552 return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
549 type, 553 type,
550 is_instance_lbl, 554 is_instance_lbl,
551 is_not_instance_lbl); 555 is_not_instance_lbl);
552 // Fall through to runtime call. 556 // Fall through to runtime call.
553 } 557 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 // return false here if the instance is null (and if the type is 606 // return false here if the instance is null (and if the type is
603 // instantiated). 607 // instantiated).
604 // We can only inline this null check if the type is instantiated at compile 608 // We can only inline this null check if the type is instantiated at compile
605 // time, since an uninstantiated type at compile time could be Object or 609 // time, since an uninstantiated type at compile time could be Object or
606 // dynamic at run time. 610 // dynamic at run time.
607 __ CompareImmediate(R0, reinterpret_cast<int32_t>(Object::null())); 611 __ CompareImmediate(R0, reinterpret_cast<int32_t>(Object::null()));
608 __ b(type.IsNullType() ? &is_instance : &is_not_instance, EQ); 612 __ b(type.IsNullType() ? &is_instance : &is_not_instance, EQ);
609 } 613 }
610 614
611 // Generate inline instanceof test. 615 // Generate inline instanceof test.
612 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 616 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
613 test_cache = GenerateInlineInstanceof(token_pos, type, 617 test_cache = GenerateInlineInstanceof(token_pos, type,
614 &is_instance, &is_not_instance); 618 &is_instance, &is_not_instance);
615 619
616 // test_cache is null if there is no fall-through. 620 // test_cache is null if there is no fall-through.
617 Label done; 621 Label done;
618 if (!test_cache.IsNull()) { 622 if (!test_cache.IsNull()) {
619 // Generate runtime call. 623 // Generate runtime call.
620 // Load instantiator (R2) and its type arguments (R1). 624 // Load instantiator (R2) and its type arguments (R1).
621 __ ldm(IA, SP, (1 << R1) | (1 << R2)); 625 __ ldm(IA, SP, (1 << R1) | (1 << R2));
622 __ PushObject(Object::null_object()); // Make room for the result. 626 __ PushObject(Object::null_object()); // Make room for the result.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 // We should never return here. 701 // We should never return here.
698 __ bkpt(0); 702 __ bkpt(0);
699 703
700 __ Bind(&is_assignable); // For a null object. 704 __ Bind(&is_assignable); // For a null object.
701 // Restore instantiator (R2) and its type arguments (R1). 705 // Restore instantiator (R2) and its type arguments (R1).
702 __ PopList((1 << R1) | (1 << R2)); 706 __ PopList((1 << R1) | (1 << R2));
703 return; 707 return;
704 } 708 }
705 709
706 // Generate inline type check, linking to runtime call if not assignable. 710 // Generate inline type check, linking to runtime call if not assignable.
707 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 711 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
708 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 712 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
709 &is_assignable, &runtime_call); 713 &is_assignable, &runtime_call);
710 714
711 __ Bind(&runtime_call); 715 __ Bind(&runtime_call);
712 // Load instantiator (R2) and its type arguments (R1). 716 // Load instantiator (R2) and its type arguments (R1).
713 __ ldm(IA, SP, (1 << R1) | (1 << R2)); 717 __ ldm(IA, SP, (1 << R1) | (1 << R2));
714 __ PushObject(Object::null_object()); // Make room for the result. 718 __ PushObject(Object::null_object()); // Make room for the result.
715 __ Push(R0); // Push the source object. 719 __ Push(R0); // Push the source object.
716 __ PushObject(dst_type); // Push the type of the destination. 720 __ PushObject(dst_type); // Push the type of the destination.
717 // Push instantiator (R2) and its type arguments (R1). 721 // Push instantiator (R2) and its type arguments (R1).
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 // R5 is arg_pos as Smi. 858 // R5 is arg_pos as Smi.
855 // Point to next named entry. 859 // Point to next named entry.
856 __ add(R6, R6, Operand(ArgumentsDescriptor::named_entry_size())); 860 __ add(R6, R6, Operand(ArgumentsDescriptor::named_entry_size()));
857 __ rsb(R5, R5, Operand(0)); 861 __ rsb(R5, R5, Operand(0));
858 Address argument_addr(R7, R5, LSL, 1); // R5 is a negative Smi. 862 Address argument_addr(R7, R5, LSL, 1); // R5 is a negative Smi.
859 __ ldr(R5, argument_addr); 863 __ ldr(R5, argument_addr);
860 __ b(&assign_optional_parameter); 864 __ b(&assign_optional_parameter);
861 __ Bind(&load_default_value); 865 __ Bind(&load_default_value);
862 // Load R5 with default argument. 866 // Load R5 with default argument.
863 const Object& value = Object::ZoneHandle( 867 const Object& value = Object::ZoneHandle(
864 parsed_function().default_parameter_values().At( 868 zone(), parsed_function().default_parameter_values().At(
865 param_pos - num_fixed_params)); 869 param_pos - num_fixed_params));
866 __ LoadObject(R5, value); 870 __ LoadObject(R5, value);
867 __ Bind(&assign_optional_parameter); 871 __ Bind(&assign_optional_parameter);
868 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos]. 872 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
869 // We do not use the final allocation index of the variable here, i.e. 873 // We do not use the final allocation index of the variable here, i.e.
870 // scope->VariableAt(i)->index(), because captured variables still need 874 // scope->VariableAt(i)->index(), because captured variables still need
871 // to be copied to the context that is not yet allocated. 875 // to be copied to the context that is not yet allocated.
872 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 876 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
873 const Address param_addr(FP, computed_param_pos * kWordSize); 877 const Address param_addr(FP, computed_param_pos * kWordSize);
874 __ str(R5, param_addr); 878 __ str(R5, param_addr);
(...skipping 15 matching lines...) Expand all
890 for (int i = 0; i < num_opt_pos_params; i++) { 894 for (int i = 0; i < num_opt_pos_params; i++) {
891 Label next_parameter; 895 Label next_parameter;
892 // Handle this optional positional parameter only if k or fewer positional 896 // Handle this optional positional parameter only if k or fewer positional
893 // arguments have been passed, where k is param_pos, the position of this 897 // arguments have been passed, where k is param_pos, the position of this
894 // optional parameter in the formal parameter list. 898 // optional parameter in the formal parameter list.
895 const int param_pos = num_fixed_params + i; 899 const int param_pos = num_fixed_params + i;
896 __ CompareImmediate(R9, param_pos); 900 __ CompareImmediate(R9, param_pos);
897 __ b(&next_parameter, GT); 901 __ b(&next_parameter, GT);
898 // Load R5 with default argument. 902 // Load R5 with default argument.
899 const Object& value = Object::ZoneHandle( 903 const Object& value = Object::ZoneHandle(
900 parsed_function().default_parameter_values().At(i)); 904 zone(), parsed_function().default_parameter_values().At(i));
901 __ LoadObject(R5, value); 905 __ LoadObject(R5, value);
902 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos]. 906 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
903 // We do not use the final allocation index of the variable here, i.e. 907 // We do not use the final allocation index of the variable here, i.e.
904 // scope->VariableAt(i)->index(), because captured variables still need 908 // scope->VariableAt(i)->index(), because captured variables still need
905 // to be copied to the context that is not yet allocated. 909 // to be copied to the context that is not yet allocated.
906 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 910 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
907 const Address param_addr(FP, computed_param_pos * kWordSize); 911 const Address param_addr(FP, computed_param_pos * kWordSize);
908 __ str(R5, param_addr); 912 __ str(R5, param_addr);
909 __ Bind(&next_parameter); 913 __ Bind(&next_parameter);
910 } 914 }
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 } 1205 }
1202 1206
1203 1207
1204 void FlowGraphCompiler::EmitEdgeCounter() { 1208 void FlowGraphCompiler::EmitEdgeCounter() {
1205 // We do not check for overflow when incrementing the edge counter. The 1209 // We do not check for overflow when incrementing the edge counter. The
1206 // function should normally be optimized long before the counter can 1210 // function should normally be optimized long before the counter can
1207 // overflow; and though we do not reset the counters when we optimize or 1211 // overflow; and though we do not reset the counters when we optimize or
1208 // deoptimize, there is a bound on the number of 1212 // deoptimize, there is a bound on the number of
1209 // optimization/deoptimization cycles we will attempt. 1213 // optimization/deoptimization cycles we will attempt.
1210 ASSERT(assembler_->constant_pool_allowed()); 1214 ASSERT(assembler_->constant_pool_allowed());
1211 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); 1215 const Array& counter = Array::ZoneHandle(zone(), Array::New(1, Heap::kOld));
1212 counter.SetAt(0, Smi::Handle(Smi::New(0))); 1216 counter.SetAt(0, Smi::Handle(zone(), Smi::New(0)));
1213 __ Comment("Edge counter"); 1217 __ Comment("Edge counter");
1214 __ LoadUniqueObject(R0, counter); 1218 __ LoadUniqueObject(R0, counter);
1215 intptr_t increment_start = assembler_->CodeSize(); 1219 intptr_t increment_start = assembler_->CodeSize();
1216 #if defined(DEBUG) 1220 #if defined(DEBUG)
1217 bool old_use_far_branches = assembler_->use_far_branches(); 1221 bool old_use_far_branches = assembler_->use_far_branches();
1218 assembler_->set_use_far_branches(true); 1222 assembler_->set_use_far_branches(true);
1219 #endif // DEBUG 1223 #endif // DEBUG
1220 __ ldr(IP, FieldAddress(R0, Array::element_offset(0))); 1224 __ ldr(IP, FieldAddress(R0, Array::element_offset(0)));
1221 __ add(IP, IP, Operand(Smi::RawValue(1))); 1225 __ add(IP, IP, Operand(Smi::RawValue(1)));
1222 __ StoreIntoSmiField(FieldAddress(R0, Array::element_offset(0)), IP); 1226 __ StoreIntoSmiField(FieldAddress(R0, Array::element_offset(0)), IP);
(...skipping 16 matching lines...) Expand all
1239 } 1243 }
1240 1244
1241 1245
1242 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1246 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1243 ExternalLabel* target_label, 1247 ExternalLabel* target_label,
1244 const ICData& ic_data, 1248 const ICData& ic_data,
1245 intptr_t argument_count, 1249 intptr_t argument_count,
1246 intptr_t deopt_id, 1250 intptr_t deopt_id,
1247 intptr_t token_pos, 1251 intptr_t token_pos,
1248 LocationSummary* locs) { 1252 LocationSummary* locs) {
1249 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1253 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1250 // Each ICData propagated from unoptimized to optimized code contains the 1254 // Each ICData propagated from unoptimized to optimized code contains the
1251 // function that corresponds to the Dart function of that IC call. Due 1255 // function that corresponds to the Dart function of that IC call. Due
1252 // to inlining in optimized code, that function may not correspond to the 1256 // to inlining in optimized code, that function may not correspond to the
1253 // top-level function (parsed_function().function()) which could be 1257 // top-level function (parsed_function().function()) which could be
1254 // reoptimized and which counter needs to be incremented. 1258 // reoptimized and which counter needs to be incremented.
1255 // Pass the function explicitly, it is used in IC stub. 1259 // Pass the function explicitly, it is used in IC stub.
1256 1260
1257 __ LoadObject(R6, parsed_function().function()); 1261 __ LoadObject(R6, parsed_function().function());
1258 __ LoadUniqueObject(R5, ic_data); 1262 __ LoadUniqueObject(R5, ic_data);
1259 GenerateDartCall(deopt_id, 1263 GenerateDartCall(deopt_id,
1260 token_pos, 1264 token_pos,
1261 target_label, 1265 target_label,
1262 RawPcDescriptors::kIcCall, 1266 RawPcDescriptors::kIcCall,
1263 locs); 1267 locs);
1264 __ Drop(argument_count); 1268 __ Drop(argument_count);
1265 } 1269 }
1266 1270
1267 1271
1268 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1272 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
1269 const ICData& ic_data, 1273 const ICData& ic_data,
1270 intptr_t argument_count, 1274 intptr_t argument_count,
1271 intptr_t deopt_id, 1275 intptr_t deopt_id,
1272 intptr_t token_pos, 1276 intptr_t token_pos,
1273 LocationSummary* locs) { 1277 LocationSummary* locs) {
1274 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1278 ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
1275 __ LoadUniqueObject(R5, ic_data); 1279 __ LoadUniqueObject(R5, ic_data);
1276 GenerateDartCall(deopt_id, 1280 GenerateDartCall(deopt_id,
1277 token_pos, 1281 token_pos,
1278 target_label, 1282 target_label,
1279 RawPcDescriptors::kIcCall, 1283 RawPcDescriptors::kIcCall,
1280 locs); 1284 locs);
1281 __ Drop(argument_count); 1285 __ Drop(argument_count);
1282 } 1286 }
1283 1287
1284 1288
1285 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1289 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1286 const ICData& ic_data, 1290 const ICData& ic_data,
1287 intptr_t argument_count, 1291 intptr_t argument_count,
1288 intptr_t deopt_id, 1292 intptr_t deopt_id,
1289 intptr_t token_pos, 1293 intptr_t token_pos,
1290 LocationSummary* locs) { 1294 LocationSummary* locs) {
1291 MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table(); 1295 MegamorphicCacheTable* table = Isolate::Current()->megamorphic_cache_table();
1292 const String& name = String::Handle(ic_data.target_name()); 1296 const String& name = String::Handle(zone(), ic_data.target_name());
1293 const Array& arguments_descriptor = 1297 const Array& arguments_descriptor =
1294 Array::ZoneHandle(ic_data.arguments_descriptor()); 1298 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1295 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1299 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1296 const MegamorphicCache& cache = 1300 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(
1297 MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor)); 1301 zone(), table->Lookup(name, arguments_descriptor));
1298 const Register receiverR = R0; 1302 const Register receiverR = R0;
1299 const Register cacheR = R1; 1303 const Register cacheR = R1;
1300 const Register targetR = R1; 1304 const Register targetR = R1;
1301 __ LoadFromOffset(kWord, receiverR, SP, (argument_count - 1) * kWordSize); 1305 __ LoadFromOffset(kWord, receiverR, SP, (argument_count - 1) * kWordSize);
1302 __ LoadObject(cacheR, cache); 1306 __ LoadObject(cacheR, cache);
1303 1307
1304 if (FLAG_use_megamorphic_stub) { 1308 if (FLAG_use_megamorphic_stub) {
1305 __ BranchLink(&StubCode::MegamorphicLookupLabel()); 1309 __ BranchLink(&StubCode::MegamorphicLookupLabel());
1306 } else { 1310 } else {
1307 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); 1311 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 intptr_t argument_count, 1521 intptr_t argument_count,
1518 const Array& argument_names, 1522 const Array& argument_names,
1519 Label* failed, 1523 Label* failed,
1520 Label* match_found, 1524 Label* match_found,
1521 intptr_t deopt_id, 1525 intptr_t deopt_id,
1522 intptr_t token_index, 1526 intptr_t token_index,
1523 LocationSummary* locs) { 1527 LocationSummary* locs) {
1524 ASSERT(is_optimizing()); 1528 ASSERT(is_optimizing());
1525 __ Comment("EmitTestAndCall"); 1529 __ Comment("EmitTestAndCall");
1526 const Array& arguments_descriptor = 1530 const Array& arguments_descriptor =
1527 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 1531 Array::ZoneHandle(zone(), ArgumentsDescriptor::New(argument_count,
1528 argument_names)); 1532 argument_names));
1529 1533
1530 // Load receiver into R0. 1534 // Load receiver into R0.
1531 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); 1535 __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
1532 __ LoadObject(R4, arguments_descriptor); 1536 __ LoadObject(R4, arguments_descriptor);
1533 1537
1534 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid; 1538 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1535 const intptr_t kNumChecks = ic_data.NumberOfChecks(); 1539 const intptr_t kNumChecks = ic_data.NumberOfChecks();
1536 1540
1537 ASSERT(!ic_data.IsNull() && (kNumChecks > 0)); 1541 ASSERT(!ic_data.IsNull() && (kNumChecks > 0));
1538 1542
1539 Label after_smi_test; 1543 Label after_smi_test;
1540 __ tst(R0, Operand(kSmiTagMask)); 1544 __ tst(R0, Operand(kSmiTagMask));
1541 if (kFirstCheckIsSmi) { 1545 if (kFirstCheckIsSmi) {
1542 // Jump if receiver is not Smi. 1546 // Jump if receiver is not Smi.
1543 if (kNumChecks == 1) { 1547 if (kNumChecks == 1) {
1544 __ b(failed, NE); 1548 __ b(failed, NE);
1545 } else { 1549 } else {
1546 __ b(&after_smi_test, NE); 1550 __ b(&after_smi_test, NE);
1547 } 1551 }
1548 // Do not use the code from the function, but let the code be patched so 1552 // Do not use the code from the function, but let the code be patched so
1549 // that we can record the outgoing edges to other code. 1553 // that we can record the outgoing edges to other code.
1550 GenerateDartCall(deopt_id, 1554 GenerateDartCall(deopt_id,
1551 token_index, 1555 token_index,
1552 &StubCode::CallStaticFunctionLabel(), 1556 &StubCode::CallStaticFunctionLabel(),
1553 RawPcDescriptors::kOther, 1557 RawPcDescriptors::kOther,
1554 locs); 1558 locs);
1555 const Function& function = Function::Handle(ic_data.GetTargetAt(0)); 1559 const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
1556 AddStaticCallTarget(function); 1560 AddStaticCallTarget(function);
1557 __ Drop(argument_count); 1561 __ Drop(argument_count);
1558 if (kNumChecks > 1) { 1562 if (kNumChecks > 1) {
1559 __ b(match_found); 1563 __ b(match_found);
1560 } 1564 }
1561 } else { 1565 } else {
1562 // Receiver is Smi, but Smi is not a valid class therefore fail. 1566 // Receiver is Smi, but Smi is not a valid class therefore fail.
1563 // (Smi class must be first in the list). 1567 // (Smi class must be first in the list).
1564 __ b(failed, EQ); 1568 __ b(failed, EQ);
1565 } 1569 }
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 DRegister dreg = EvenDRegisterOf(reg); 1904 DRegister dreg = EvenDRegisterOf(reg);
1901 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1905 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1902 } 1906 }
1903 1907
1904 1908
1905 #undef __ 1909 #undef __
1906 1910
1907 } // namespace dart 1911 } // namespace dart
1908 1912
1909 #endif // defined TARGET_ARCH_ARM 1913 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/flow_graph_compiler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698