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

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

Issue 14192032: Implement missing features to run Hello world! in checked mode on simulated ARM. (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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_arm.cc ('k') | runtime/vm/flow_graph_compiler_ia32.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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 const Register kTempReg = kNoRegister; 278 const Register kTempReg = kNoRegister;
279 return GenerateCallSubtypeTestStub(kTestTypeOneArg, 279 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
280 kInstanceReg, 280 kInstanceReg,
281 kTypeArgumentsReg, 281 kTypeArgumentsReg,
282 kTempReg, 282 kTempReg,
283 is_instance_lbl, 283 is_instance_lbl,
284 is_not_instance_lbl); 284 is_not_instance_lbl);
285 } 285 }
286 286
287 287
288 // Generates inlined check if 'type' is a type parameter or type itself
289 // R0: instance (preserved).
288 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 290 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
289 intptr_t token_pos, 291 intptr_t token_pos,
290 const AbstractType& type, 292 const AbstractType& type,
291 Label* is_instance_lbl, 293 Label* is_instance_lbl,
292 Label* is_not_instance_lbl) { 294 Label* is_not_instance_lbl) {
293 UNIMPLEMENTED(); 295 __ Comment("UninstantiatedTypeTest");
294 return NULL; 296 ASSERT(!type.IsInstantiated());
297 // Skip check if destination is a dynamic type.
298 if (type.IsTypeParameter()) {
299 const TypeParameter& type_param = TypeParameter::Cast(type);
300 // Load instantiator (or null) and instantiator type arguments on stack.
301 __ ldr(R1, Address(SP, 0)); // Get instantiator type arguments.
302 // R1: instantiator type arguments.
303 // Check if type argument is dynamic.
304 __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
305 __ b(is_instance_lbl, EQ);
306 // Can handle only type arguments that are instances of TypeArguments.
307 // (runtime checks canonicalize type arguments).
308 Label fall_through;
309 __ CompareClassId(R1, kTypeArgumentsCid, R2);
310 __ b(&fall_through, NE);
311 __ ldr(R2,
312 FieldAddress(R1, TypeArguments::type_at_offset(type_param.index())));
313 // R2: concrete type of type.
314 // Check if type argument is dynamic.
315 __ CompareObject(R2, Type::ZoneHandle(Type::DynamicType()));
316 __ b(is_instance_lbl, EQ);
317 __ CompareImmediate(R2, reinterpret_cast<intptr_t>(Object::null()));
318 __ b(is_instance_lbl, EQ);
319 const Type& object_type = Type::ZoneHandle(Type::ObjectType());
320 __ CompareObject(R2, object_type);
321 __ b(is_instance_lbl, EQ);
322
323 // For Smi check quickly against int and num interfaces.
324 Label not_smi;
325 __ tst(R0, ShifterOperand(kSmiTagMask)); // Value is Smi?
326 __ b(&not_smi, NE);
327 __ CompareObject(R2, Type::ZoneHandle(Type::IntType()));
328 __ b(is_instance_lbl, EQ);
329 __ CompareObject(R2, Type::ZoneHandle(Type::Number()));
330 __ b(is_instance_lbl, EQ);
331 // Smi must be handled in runtime.
332 __ b(&fall_through);
333
334 __ Bind(&not_smi);
335 // R1: instantiator type arguments.
336 // R0: instance.
337 const Register kInstanceReg = R0;
338 const Register kTypeArgumentsReg = R1;
339 const Register kTempReg = kNoRegister;
340 const SubtypeTestCache& type_test_cache =
341 SubtypeTestCache::ZoneHandle(
342 GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
343 kInstanceReg,
344 kTypeArgumentsReg,
345 kTempReg,
346 is_instance_lbl,
347 is_not_instance_lbl));
348 __ Bind(&fall_through);
349 return type_test_cache.raw();
350 }
351 if (type.IsType()) {
352 const Register kInstanceReg = R0;
353 const Register kTypeArgumentsReg = R1;
354 __ tst(kInstanceReg, ShifterOperand(kSmiTagMask)); // Is instance Smi?
355 __ b(is_not_instance_lbl, EQ);
356 __ ldr(kTypeArgumentsReg, Address(SP, 0)); // Instantiator type args.
357 // Uninstantiated type class is known at compile time, but the type
358 // arguments are determined at runtime by the instantiator.
359 const Register kTempReg = kNoRegister;
360 return GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
361 kInstanceReg,
362 kTypeArgumentsReg,
363 kTempReg,
364 is_instance_lbl,
365 is_not_instance_lbl);
366 }
367 return SubtypeTestCache::null();
295 } 368 }
296 369
297 370
298 // Inputs: 371 // Inputs:
299 // - R0: instance being type checked (preserved). 372 // - R0: instance being type checked (preserved).
300 // - R1: optional instantiator type arguments (preserved). 373 // - R1: optional instantiator type arguments (preserved).
301 // Clobbers R2, R3. 374 // Clobbers R2, R3.
302 // Returns: 375 // Returns:
303 // - preserved instance in R0 and optional instantiator type arguments in R1. 376 // - preserved instance in R0 and optional instantiator type arguments in R1.
304 // Note that this inlined code must be followed by the runtime_call code, as it 377 // Note that this inlined code must be followed by the runtime_call code, as it
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 intptr_t deopt_id, 460 intptr_t deopt_id,
388 const AbstractType& dst_type, 461 const AbstractType& dst_type,
389 const String& dst_name, 462 const String& dst_name,
390 LocationSummary* locs) { 463 LocationSummary* locs) {
391 ASSERT(token_pos >= 0); 464 ASSERT(token_pos >= 0);
392 ASSERT(!dst_type.IsNull()); 465 ASSERT(!dst_type.IsNull());
393 ASSERT(dst_type.IsFinalized()); 466 ASSERT(dst_type.IsFinalized());
394 // Assignable check is skipped in FlowGraphBuilder, not here. 467 // Assignable check is skipped in FlowGraphBuilder, not here.
395 ASSERT(dst_type.IsMalformed() || 468 ASSERT(dst_type.IsMalformed() ||
396 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 469 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
397 // Preserve instantiator and its type arguments. 470 // Preserve instantiator (R2) and its type arguments (R1).
398 __ PushList((1 << R1) | (1 << R2)); 471 __ PushList((1 << R1) | (1 << R2));
399 // A null object is always assignable and is returned as result. 472 // A null object is always assignable and is returned as result.
400 Label is_assignable, runtime_call; 473 Label is_assignable, runtime_call;
401 __ CompareImmediate(R0, reinterpret_cast<int32_t>(Object::null())); 474 __ CompareImmediate(R0, reinterpret_cast<int32_t>(Object::null()));
402 __ b(&is_assignable, EQ); 475 __ b(&is_assignable, EQ);
403 476
404 if (!FLAG_eliminate_type_checks) { 477 if (!FLAG_eliminate_type_checks) {
405 // If type checks are not eliminated during the graph building then 478 // If type checks are not eliminated during the graph building then
406 // a transition sentinel can be seen here. 479 // a transition sentinel can be seen here.
407 __ CompareObject(R0, Object::transition_sentinel()); 480 __ CompareObject(R0, Object::transition_sentinel());
(...skipping 10 matching lines...) Expand all
418 __ PushObject(dst_name); // Push the name of the destination. 491 __ PushObject(dst_name); // Push the name of the destination.
419 __ PushObject(error_message); 492 __ PushObject(error_message);
420 GenerateCallRuntime(token_pos, 493 GenerateCallRuntime(token_pos,
421 deopt_id, 494 deopt_id,
422 kMalformedTypeErrorRuntimeEntry, 495 kMalformedTypeErrorRuntimeEntry,
423 locs); 496 locs);
424 // We should never return here. 497 // We should never return here.
425 __ bkpt(0); 498 __ bkpt(0);
426 499
427 __ Bind(&is_assignable); // For a null object. 500 __ Bind(&is_assignable); // For a null object.
428 // Restore instantiator and its type arguments. 501 // Restore instantiator (R2) and its type arguments (R1).
429 __ PopList((1 << R1) | (1 << R2)); 502 __ PopList((1 << R1) | (1 << R2));
430 return; 503 return;
431 } 504 }
432 505
433 // Generate inline type check, linking to runtime call if not assignable. 506 // Generate inline type check, linking to runtime call if not assignable.
434 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 507 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
435 test_cache = GenerateInlineInstanceof(token_pos, dst_type, 508 test_cache = GenerateInlineInstanceof(token_pos, dst_type,
436 &is_assignable, &runtime_call); 509 &is_assignable, &runtime_call);
437 510
438 __ Bind(&runtime_call); 511 __ Bind(&runtime_call);
439 // Load instantiator and its type arguments. 512 // Load instantiator (R2) and its type arguments (R1).
440 __ ldm(IA, SP, (1 << R1) | (1 << R2)); 513 __ ldm(IA, SP, (1 << R1) | (1 << R2));
441 __ PushObject(Object::ZoneHandle()); // Make room for the result. 514 __ PushObject(Object::ZoneHandle()); // Make room for the result.
442 __ Push(R0); // Push the source object. 515 __ Push(R0); // Push the source object.
443 __ PushObject(dst_type); // Push the type of the destination. 516 __ PushObject(dst_type); // Push the type of the destination.
444 // Push instantiator and its type arguments. 517 // Push instantiator (R2) and its type arguments (R1).
445 __ PushList((1 << R1) | (1 << R2)); 518 __ PushList((1 << R1) | (1 << R2));
446 __ PushObject(dst_name); // Push the name of the destination. 519 __ PushObject(dst_name); // Push the name of the destination.
447 __ LoadObject(R0, test_cache); 520 __ LoadObject(R0, test_cache);
448 __ Push(R0); 521 __ Push(R0);
449 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs); 522 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
450 // Pop the parameters supplied to the runtime entry. The result of the 523 // Pop the parameters supplied to the runtime entry. The result of the
451 // type check runtime call is the checked value. 524 // type check runtime call is the checked value.
452 __ Drop(6); 525 __ Drop(6);
453 __ Pop(R0); 526 __ Pop(R0);
454 527
455 __ Bind(&is_assignable); 528 __ Bind(&is_assignable);
456 // Restore instantiator and its type arguments. 529 // Restore instantiator (R2) and its type arguments (R1).
457 __ PopList((1 << R1) | (1 << R2)); 530 __ PopList((1 << R1) | (1 << R2));
458 } 531 }
459 532
460 533
461 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { 534 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
462 if (!is_optimizing()) { 535 if (!is_optimizing()) {
463 if (FLAG_enable_type_checks && instr->IsAssertAssignable()) { 536 if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
464 AssertAssignableInstr* assert = instr->AsAssertAssignable(); 537 AssertAssignableInstr* assert = instr->AsAssertAssignable();
465 AddCurrentDescriptor(PcDescriptors::kDeopt, 538 AddCurrentDescriptor(PcDescriptors::kDeopt,
466 assert->deopt_id(), 539 assert->deopt_id(),
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 1443 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1371 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); 1444 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex));
1372 } 1445 }
1373 1446
1374 1447
1375 #undef __ 1448 #undef __
1376 1449
1377 } // namespace dart 1450 } // namespace dart
1378 1451
1379 #endif // defined TARGET_ARCH_ARM 1452 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698