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

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

Issue 263243002: Enables many language tests for arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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
« no previous file with comments | « runtime/vm/simulator_arm64.cc ('k') | tests/language/language.status » ('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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/heap.h" 13 #include "vm/heap.h"
14 #include "vm/instructions.h" 14 #include "vm/instructions.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/stack_frame.h" 16 #include "vm/stack_frame.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/tags.h" 18 #include "vm/tags.h"
19 19
20 #define __ assembler-> 20 #define __ assembler->
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); 24 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
25 DEFINE_FLAG(bool, use_slow_path, false, 25 DEFINE_FLAG(bool, use_slow_path, false,
26 "Set to true for debugging & verifying the slow paths."); 26 "Set to true for debugging & verifying the slow paths.");
27 DECLARE_FLAG(bool, trace_optimized_ic_calls);
27 28
28 // Input parameters: 29 // Input parameters:
29 // LR : return address. 30 // LR : return address.
30 // SP : address of last argument in argument array. 31 // SP : address of last argument in argument array.
31 // SP + 8*R4 - 8 : address of first argument in argument array. 32 // SP + 8*R4 - 8 : address of first argument in argument array.
32 // SP + 8*R4 : address of return value. 33 // SP + 8*R4 : address of return value.
33 // R5 : address of the runtime function to call. 34 // R5 : address of the runtime function to call.
34 // R4 : number of arguments to the call. 35 // R4 : number of arguments to the call.
35 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 36 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
36 const intptr_t isolate_offset = NativeArguments::isolate_offset(); 37 const intptr_t isolate_offset = NativeArguments::isolate_offset();
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 __ StoreToOffset(R3, CTX, Isolate::top_context_offset()); 347 __ StoreToOffset(R3, CTX, Isolate::top_context_offset());
347 348
348 // Cache Context pointer into CTX while executing Dart code. 349 // Cache Context pointer into CTX while executing Dart code.
349 __ mov(CTX, R2); 350 __ mov(CTX, R2);
350 351
351 __ LeaveFrame(); 352 __ LeaveFrame();
352 __ ret(); 353 __ ret();
353 } 354 }
354 355
355 356
357 // Input parameters:
358 // R4: arguments descriptor array.
356 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { 359 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
357 __ Stop("GenerateCallStaticFunctionStub"); 360 // Create a stub frame as we are pushing some objects on the stack before
358 } 361 // calling into the runtime.
359 362 __ EnterStubFrame();
360 363 // Setup space on stack for return value and preserve arguments descriptor.
364 __ Push(R4);
365 __ PushObject(Object::null_object(), PP);
366 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
367 // Get Code object result and restore arguments descriptor array.
368 __ Pop(R0);
369 __ Pop(R4);
370 // Remove the stub frame.
371 __ LeaveStubFrame();
372 // Jump to the dart function.
373 __ LoadFieldFromOffset(R0, R0, Code::instructions_offset());
374 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag, kNoPP);
375 __ br(R0);
376 }
377
378
379 // Called from a static call only when an invalid code has been entered
380 // (invalid because its function was optimized or deoptimized).
381 // R4: arguments descriptor array.
361 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 382 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
362 __ Stop("GenerateFixCallersTargetStub"); 383 // Create a stub frame as we are pushing some objects on the stack before
384 // calling into the runtime.
385 __ EnterStubFrame();
386 // Setup space on stack for return value and preserve arguments descriptor.
387 __ Push(R4);
388 __ PushObject(Object::null_object(), PP);
389 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
390 // Get Code object result and restore arguments descriptor array.
391 __ Pop(R0);
392 __ Pop(R4);
393 // Remove the stub frame.
394 __ LeaveStubFrame();
395 // Jump to the dart function.
396 __ LoadFieldFromOffset(R0, R0, Code::instructions_offset());
397 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag, kNoPP);
398 __ br(R0);
399 }
400
401
402 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
403 intptr_t deopt_reason,
404 uword saved_registers_address);
405
406 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
407
408
409 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
410 // This stub translates optimized frame into unoptimized frame. The optimized
411 // frame can contain values in registers and on stack, the unoptimized
412 // frame contains all values on stack.
413 // Deoptimization occurs in following steps:
414 // - Push all registers that can contain values.
415 // - Call C routine to copy the stack and saved registers into temporary buffer.
416 // - Adjust caller's frame to correct unoptimized frame size.
417 // - Fill the unoptimized frame.
418 // - Materialize objects that require allocation (e.g. Double instances).
419 // GC can occur only after frame is fully rewritten.
420 // Stack after TagAndPushPP() below:
421 // +------------------+
422 // | Saved PP | <- PP
423 // +------------------+
424 // | PC marker | <- TOS
425 // +------------------+
426 // | Saved FP | <- FP of stub
427 // +------------------+
428 // | return-address | (deoptimization point)
429 // +------------------+
430 // | ... | <- SP of optimized frame
431 //
432 // Parts of the code cannot GC, part of the code can GC.
433 static void GenerateDeoptimizationSequence(Assembler* assembler,
434 bool preserve_result) {
435 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
436 // is no need to set the correct PC marker or load PP, since they get patched.
437 __ EnterFrame(0);
438 __ Push(ZR);
439 __ TagAndPushPP();
440
441 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
442 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
443 const intptr_t saved_result_slot_from_fp =
444 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0);
445 // Result in R0 is preserved as part of pushing all registers below.
446
447 // Push registers in their enumeration order: lowest register number at
448 // lowest address.
449 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
450 const Register r = static_cast<Register>(i);
451 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex));
452 }
453
454 for (intptr_t reg_idx = kNumberOfVRegisters - 1; reg_idx >= 0; reg_idx--) {
455 VRegister vreg = static_cast<VRegister>(reg_idx);
456 // TODO(zra): Save whole V registers. For now, push twice.
457 __ PushDouble(vreg);
458 __ PushDouble(vreg);
459 }
460
461 __ mov(R0, SP); // Pass address of saved registers block.
462 __ ReserveAlignedFrameSpace(0);
463 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1);
464 // Result (R0) is stack-size (FP - SP) in bytes.
465
466 if (preserve_result) {
467 // Restore result into R1 temporarily.
468 __ LoadFromOffset(R1, FP, saved_result_slot_from_fp * kWordSize);
469 }
470
471 // There is a Dart Frame on the stack. We must restore PP and leave frame.
472 __ LeaveDartFrame();
473 __ sub(TMP, FP, Operand(R0));
474 __ mov(SP, TMP);
475
476 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
477 // is no need to set the correct PC marker or load PP, since they get patched.
478 __ EnterFrame(0);
479 __ Push(ZR);
480 __ TagAndPushPP();
481
482 if (preserve_result) {
483 __ Push(R1); // Preserve result as first local.
484 }
485 __ ReserveAlignedFrameSpace(0);
486 __ mov(R0, FP); // Pass last FP as parameter in R0.
487 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
488 if (preserve_result) {
489 // Restore result into R1.
490 __ LoadFromOffset(R1, FP, kFirstLocalSlotFromFp * kWordSize);
491 }
492 // Code above cannot cause GC.
493 // There is a Dart Frame on the stack. We must restore PP and leave frame.
494 __ LeaveDartFrame();
495
496 // Frame is fully rewritten at this point and it is safe to perform a GC.
497 // Materialize any objects that were deferred by FillFrame because they
498 // require allocation.
499 __ EnterStubFrame();
500 if (preserve_result) {
501 __ Push(ZR); // Workaround for dropped stack slot during GC.
502 __ Push(R1); // Preserve result, it will be GC-d here.
503 }
504 __ Push(ZR); // Space for the result.
505 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
506 // Result tells stub how many bytes to remove from the expression stack
507 // of the bottom-most frame. They were used as materialization arguments.
508 __ Pop(R1);
509 __ SmiUntag(R1);
510 if (preserve_result) {
511 __ Pop(R0); // Restore result.
512 __ Drop(1); // Workaround for dropped stack slot during GC.
513 }
514 __ LeaveStubFrame();
515 // Remove materialization arguments.
516 __ add(TMP, SP, Operand(R1, UXTX, 0));
517 __ mov(SP, TMP);
518 __ ret();
363 } 519 }
364 520
365 521
366 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 522 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
367 __ Stop("GenerateDeoptimizeLazyStub"); 523 // Correct return address to point just after the call that is being
524 // deoptimized.
525 __ AddImmediate(LR, LR, -CallPattern::kLengthInBytes, kNoPP);
526 GenerateDeoptimizationSequence(assembler, true); // Preserve R0.
368 } 527 }
369 528
370 529
371 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 530 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
372 __ Stop("GenerateDeoptimizeStub"); 531 GenerateDeoptimizationSequence(assembler, false); // Don't preserve R0.
373 } 532 }
374 533
375 534
376 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 535 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
377 __ Stop("GenerateMegamorphicMissStub"); 536 __ EnterStubFrame();
378 } 537
379 538 // Load the receiver.
380 539 __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset());
540 __ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi.
541 __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize);
542
543 // Preserve IC data and arguments descriptor.
544 __ Push(R5);
545 __ Push(R4);
546
547 // Push space for the return value.
548 // Push the receiver.
549 // Push IC data object.
550 // Push arguments descriptor array.
551 __ PushObject(Object::null_object(), PP);
552 __ Push(R6);
553 __ Push(R5);
554 __ Push(R4);
555 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
556 // Remove arguments.
557 __ Drop(3);
558 __ Pop(R0); // Get result into R0 (target function).
559
560 // Restore IC data and arguments descriptor.
561 __ Pop(R4);
562 __ Pop(R5);
563
564 __ LeaveStubFrame();
565
566 // Tail-call to target function.
567 __ LoadFieldFromOffset(R2, R0, Function::code_offset());
568 __ LoadFieldFromOffset(R2, R2, Code::instructions_offset());
569 __ AddImmediate(R2, R2, Instructions::HeaderSize() - kHeapObjectTag, PP);
570 __ br(R2);
571 }
572
573
381 // Called for inline allocation of arrays. 574 // Called for inline allocation of arrays.
382 // Input parameters: 575 // Input parameters:
383 // LR: return address. 576 // LR: return address.
384 // R2: array length as Smi. 577 // R2: array length as Smi.
385 // R1: array element type (either NULL or an instantiated type). 578 // R1: array element type (either NULL or an instantiated type).
386 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. 579 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
387 // The newly allocated object is returned in R0. 580 // The newly allocated object is returned in R0.
388 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 581 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
389 Label slow_case; 582 Label slow_case;
390 if (FLAG_inline_alloc) { 583 if (FLAG_inline_alloc) {
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 // calling into the runtime. 1159 // calling into the runtime.
967 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime. 1160 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime.
968 // Setup space on stack for return value. 1161 // Setup space on stack for return value.
969 __ PushObject(Object::null_object(), PP); 1162 __ PushObject(Object::null_object(), PP);
970 __ PushObject(cls, PP); // Push class of object to be allocated. 1163 __ PushObject(cls, PP); // Push class of object to be allocated.
971 if (is_cls_parameterized) { 1164 if (is_cls_parameterized) {
972 // Push type arguments. 1165 // Push type arguments.
973 __ Push(R1); 1166 __ Push(R1);
974 } else { 1167 } else {
975 // Push null type arguments. 1168 // Push null type arguments.
976 __ Push(R2); 1169 __ PushObject(Object::null_object(), PP);
977 } 1170 }
978 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. 1171 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
979 __ Drop(2); // Pop arguments. 1172 __ Drop(2); // Pop arguments.
980 __ Pop(R0); // Pop result (newly allocated object). 1173 __ Pop(R0); // Pop result (newly allocated object).
981 // R0: new object 1174 // R0: new object
982 // Restore the frame pointer. 1175 // Restore the frame pointer.
983 __ LeaveStubFrame(); 1176 __ LeaveStubFrame();
984 __ ret(); 1177 __ ret();
985 } 1178 }
986 1179
987 1180
988 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1181 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
989 __ Stop("GenerateCallNoSuchMethodFunctionStub"); 1182 __ Stop("GenerateCallNoSuchMethodFunctionStub");
990 } 1183 }
991 1184
992 1185
1186 // R6: function object.
1187 // R5: inline cache data object.
1188 // Cannot use function object from ICData as it may be the inlined
1189 // function and not the top-scope function.
993 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1190 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
994 __ Stop("GenerateOptimizedUsageCounterIncrement"); 1191 Register ic_reg = R5;
1192 Register func_reg = R6;
1193 if (FLAG_trace_optimized_ic_calls) {
1194 __ EnterStubFrame();
1195 __ Push(R6); // Preserve.
1196 __ Push(R5); // Preserve.
1197 __ Push(ic_reg); // Argument.
1198 __ Push(func_reg); // Argument.
1199 __ CallRuntime(kTraceICCallRuntimeEntry, 2);
1200 __ Drop(2); // Discard argument;
1201 __ Pop(R5); // Restore.
1202 __ Pop(R6); // Restore.
1203 __ LeaveStubFrame();
1204 }
1205 __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset());
1206 __ add(R7, R7, Operand(1));
1207 __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset());
995 } 1208 }
996 1209
997 1210
998 // Loads function into 'temp_reg'. 1211 // Loads function into 'temp_reg'.
999 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1212 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1000 Register temp_reg) { 1213 Register temp_reg) {
1001 Register ic_reg = R5; 1214 Register ic_reg = R5;
1002 Register func_reg = temp_reg; 1215 Register func_reg = temp_reg;
1003 ASSERT(temp_reg == R6); 1216 ASSERT(temp_reg == R6);
1004 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset()); 1217 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset());
(...skipping 30 matching lines...) Expand all
1035 __ b(&ok, EQ); 1248 __ b(&ok, EQ);
1036 __ Stop("Incorrect stub for IC data"); 1249 __ Stop("Incorrect stub for IC data");
1037 __ Bind(&ok); 1250 __ Bind(&ok);
1038 } 1251 }
1039 #endif // DEBUG 1252 #endif // DEBUG
1040 1253
1041 // Check single stepping. 1254 // Check single stepping.
1042 Label not_stepping; 1255 Label not_stepping;
1043 __ LoadFieldFromOffset(R6, CTX, Context::isolate_offset()); 1256 __ LoadFieldFromOffset(R6, CTX, Context::isolate_offset());
1044 __ LoadFromOffset(R6, R6, Isolate::single_step_offset(), kUnsignedByte); 1257 __ LoadFromOffset(R6, R6, Isolate::single_step_offset(), kUnsignedByte);
1045 __ CompareImmediate(R6, 0, kNoPP); 1258 __ CompareRegisters(R6, ZR);
1046 __ b(&not_stepping, EQ); 1259 __ b(&not_stepping, EQ);
1047 __ EnterStubFrame(); 1260 __ EnterStubFrame();
1048 __ Push(R5); // Preserve IC data. 1261 __ Push(R5); // Preserve IC data.
1049 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1262 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1050 __ Pop(R5); 1263 __ Pop(R5);
1051 __ LeaveStubFrame(); 1264 __ LeaveStubFrame();
1052 __ Bind(&not_stepping); 1265 __ Bind(&not_stepping);
1053 1266
1054 // Load arguments descriptor into R4. 1267 // Load arguments descriptor into R4.
1055 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset()); 1268 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset());
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 1448
1236 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { 1449 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
1237 GenerateUsageCounterIncrement(assembler, R6); 1450 GenerateUsageCounterIncrement(assembler, R6);
1238 GenerateNArgsCheckInlineCacheStub( 1451 GenerateNArgsCheckInlineCacheStub(
1239 assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry); 1452 assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1240 } 1453 }
1241 1454
1242 1455
1243 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( 1456 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
1244 Assembler* assembler) { 1457 Assembler* assembler) {
1245 __ Stop("GenerateOneArgOptimizedCheckInlineCacheStub"); 1458 GenerateOptimizedUsageCounterIncrement(assembler);
1459 GenerateNArgsCheckInlineCacheStub(
1460 assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
1246 } 1461 }
1247 1462
1248 1463
1249 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( 1464 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
1250 Assembler* assembler) { 1465 Assembler* assembler) {
1251 __ Stop("GenerateTwoArgsOptimizedCheckInlineCacheStub"); 1466 GenerateOptimizedUsageCounterIncrement(assembler);
1467 GenerateNArgsCheckInlineCacheStub(
1468 assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
1252 } 1469 }
1253 1470
1254 1471
1255 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( 1472 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
1256 Assembler* assembler) { 1473 Assembler* assembler) {
1257 __ Stop("GenerateThreeArgsOptimizedCheckInlineCacheStub"); 1474 GenerateOptimizedUsageCounterIncrement(assembler);
1475 GenerateNArgsCheckInlineCacheStub(
1476 assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
1258 } 1477 }
1259 1478
1260 1479
1261 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { 1480 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
1262 __ Stop("GenerateClosureCallInlineCacheStub"); 1481 __ Stop("GenerateClosureCallInlineCacheStub");
1263 } 1482 }
1264 1483
1265 1484
1266 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1485 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1267 GenerateUsageCounterIncrement(assembler, R6); 1486 GenerateUsageCounterIncrement(assembler, R6);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { 1706 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) {
1488 __ Stop("GenerateGetStackPointerStub"); 1707 __ Stop("GenerateGetStackPointerStub");
1489 } 1708 }
1490 1709
1491 1710
1492 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { 1711 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
1493 __ Stop("GenerateJumpToExceptionHandlerStub"); 1712 __ Stop("GenerateJumpToExceptionHandlerStub");
1494 } 1713 }
1495 1714
1496 1715
1716 // Calls to the runtime to optimize the given function.
1717 // R6: function to be re-optimized.
1718 // R4: argument descriptor (preserved).
1497 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 1719 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
1498 __ Stop("GenerateOptimizeFunctionStub"); 1720 __ EnterStubFrame();
1721 __ Push(R4);
1722 // Setup space on stack for the return value.
1723 __ PushObject(Object::null_object(), PP);
1724 __ Push(R6);
1725 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
1726 __ Pop(R0); // Discard argument.
1727 __ Pop(R0); // Get Code object
1728 __ Pop(R4); // Restore argument descriptor.
1729 __ LoadFieldFromOffset(R0, R0, Code::instructions_offset());
1730 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag, PP);
1731 __ LeaveStubFrame();
1732 __ br(R0);
1733 __ hlt(0);
1499 } 1734 }
1500 1735
1501 1736
1502 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, 1737 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t,
1503 BigintCompare, 1738 BigintCompare,
1504 RawBigint* left, 1739 RawBigint* left,
1505 RawBigint* right); 1740 RawBigint* right);
1506 1741
1507 1742
1508 // Does identical check (object references are equal or not equal) with special 1743 // Does identical check (object references are equal or not equal) with special
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 1820
1586 const Register left = R1; 1821 const Register left = R1;
1587 const Register right = R0; 1822 const Register right = R0;
1588 __ LoadFromOffset(left, SP, 1 * kWordSize); 1823 __ LoadFromOffset(left, SP, 1 * kWordSize);
1589 __ LoadFromOffset(right, SP, 0 * kWordSize); 1824 __ LoadFromOffset(right, SP, 0 * kWordSize);
1590 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 1825 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
1591 __ ret(); 1826 __ ret();
1592 } 1827 }
1593 1828
1594 1829
1830 // Called from optimized code only.
1831 // LR: return address.
1832 // SP + 4: left operand.
1833 // SP + 0: right operand.
1834 // Return Zero condition flag set if equal.
1595 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( 1835 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
1596 Assembler* assembler) { 1836 Assembler* assembler) {
1597 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub"); 1837 const Register temp = R2;
1838 const Register left = R1;
1839 const Register right = R0;
1840 __ LoadFromOffset(left, SP, 1 * kWordSize);
1841 __ LoadFromOffset(right, SP, 0 * kWordSize);
1842 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1843 __ ret();
1598 } 1844 }
1599 1845
1600 } // namespace dart 1846 } // namespace dart
1601 1847
1602 #endif // defined TARGET_ARCH_ARM64 1848 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm64.cc ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698