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

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

Issue 593363003: Expands the use of Immediate and Operand wrappers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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) 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"
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 // R2: array length as Smi. 641 // R2: array length as Smi.
642 // R1: array element type (either NULL or an instantiated type). 642 // R1: array element type (either NULL or an instantiated type).
643 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. 643 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
644 // The newly allocated object is returned in R0. 644 // The newly allocated object is returned in R0.
645 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 645 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
646 Label slow_case; 646 Label slow_case;
647 // Compute the size to be allocated, it is based on the array length 647 // Compute the size to be allocated, it is based on the array length
648 // and is computed as: 648 // and is computed as:
649 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 649 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
650 // Assert that length is a Smi. 650 // Assert that length is a Smi.
651 __ tsti(R2, kSmiTagMask); 651 __ tsti(R2, Immediate(kSmiTagMask));
652 if (FLAG_use_slow_path) { 652 if (FLAG_use_slow_path) {
653 __ b(&slow_case); 653 __ b(&slow_case);
654 } else { 654 } else {
655 __ b(&slow_case, NE); 655 __ b(&slow_case, NE);
656 } 656 }
657 __ cmp(R2, Operand(0)); 657 __ cmp(R2, Operand(0));
658 __ b(&slow_case, LT); 658 __ b(&slow_case, LT);
659 659
660 Isolate* isolate = Isolate::Current(); 660 Isolate* isolate = Isolate::Current();
661 Heap* heap = isolate->heap(); 661 Heap* heap = isolate->heap();
662 const intptr_t cid = kArrayCid; 662 const intptr_t cid = kArrayCid;
663 Heap::Space space = heap->SpaceForAllocation(cid); 663 Heap::Space space = heap->SpaceForAllocation(cid);
664 const uword top_address = heap->TopAddress(space); 664 const uword top_address = heap->TopAddress(space);
665 __ LoadImmediate(R8, top_address, kNoPP); 665 __ LoadImmediate(R8, top_address, kNoPP);
666 const uword end_address = heap->EndAddress(space); 666 const uword end_address = heap->EndAddress(space);
667 ASSERT(top_address < end_address); 667 ASSERT(top_address < end_address);
668 const uword top_offset = 0; 668 const uword top_offset = 0;
669 const uword end_offset = end_address - top_address; 669 const uword end_offset = end_address - top_address;
670 670
671 // Calculate and align allocation size. 671 // Calculate and align allocation size.
672 // Load new object start and calculate next object start. 672 // Load new object start and calculate next object start.
673 // R1: array element type. 673 // R1: array element type.
674 // R2: array length as Smi. 674 // R2: array length as Smi.
675 // R8: points to new space object. 675 // R8: points to new space object.
676 __ LoadFromOffset(R0, R8, top_offset, kNoPP); 676 __ LoadFromOffset(R0, R8, top_offset, kNoPP);
677 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 677 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
678 __ LoadImmediate(R3, fixed_size, kNoPP); 678 __ LoadImmediate(R3, fixed_size, kNoPP);
679 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi. 679 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi.
680 ASSERT(kSmiTagShift == 1); 680 ASSERT(kSmiTagShift == 1);
681 __ andi(R3, R3, ~(kObjectAlignment - 1)); 681 __ andi(R3, R3, Immediate(~(kObjectAlignment - 1)));
682 __ adds(R7, R3, Operand(R0)); 682 __ adds(R7, R3, Operand(R0));
683 __ b(&slow_case, VS); 683 __ b(&slow_case, VS);
684 684
685 // Check if the allocation fits into the remaining space. 685 // Check if the allocation fits into the remaining space.
686 // R0: potential new object start. 686 // R0: potential new object start.
687 // R1: array element type. 687 // R1: array element type.
688 // R2: array length as Smi. 688 // R2: array length as Smi.
689 // R3: array size. 689 // R3: array size.
690 // R7: potential next object start. 690 // R7: potential next object start.
691 // R8: points to new space object. 691 // R8: points to new space object.
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 961 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
962 if (FLAG_inline_alloc) { 962 if (FLAG_inline_alloc) {
963 Label slow_case; 963 Label slow_case;
964 Heap* heap = Isolate::Current()->heap(); 964 Heap* heap = Isolate::Current()->heap();
965 // First compute the rounded instance size. 965 // First compute the rounded instance size.
966 // R1: number of context variables. 966 // R1: number of context variables.
967 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; 967 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1;
968 __ LoadImmediate(R2, fixed_size, kNoPP); 968 __ LoadImmediate(R2, fixed_size, kNoPP);
969 __ add(R2, R2, Operand(R1, LSL, 3)); 969 __ add(R2, R2, Operand(R1, LSL, 3));
970 ASSERT(kSmiTagShift == 1); 970 ASSERT(kSmiTagShift == 1);
971 __ andi(R2, R2, ~(kObjectAlignment - 1)); 971 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1)));
972 972
973 // Now allocate the object. 973 // Now allocate the object.
974 // R1: number of context variables. 974 // R1: number of context variables.
975 // R2: object size. 975 // R2: object size.
976 const intptr_t cid = kContextCid; 976 const intptr_t cid = kContextCid;
977 Heap::Space space = heap->SpaceForAllocation(cid); 977 Heap::Space space = heap->SpaceForAllocation(cid);
978 __ LoadImmediate(R5, heap->TopAddress(space), kNoPP); 978 __ LoadImmediate(R5, heap->TopAddress(space), kNoPP);
979 __ ldr(R0, Address(R5)); 979 __ ldr(R0, Address(R5));
980 __ add(R3, R2, Operand(R0)); 980 __ add(R3, R2, Operand(R0));
981 // Check if the allocation fits into the remaining space. 981 // Check if the allocation fits into the remaining space.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); 1079 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate);
1080 1080
1081 // Helper stub to implement Assembler::StoreIntoObject. 1081 // Helper stub to implement Assembler::StoreIntoObject.
1082 // Input parameters: 1082 // Input parameters:
1083 // R0: Address being stored 1083 // R0: Address being stored
1084 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { 1084 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
1085 Label add_to_buffer; 1085 Label add_to_buffer;
1086 // Check whether this object has already been remembered. Skip adding to the 1086 // Check whether this object has already been remembered. Skip adding to the
1087 // store buffer if the object is in the store buffer already. 1087 // store buffer if the object is in the store buffer already.
1088 __ LoadFieldFromOffset(TMP, R0, Object::tags_offset(), kNoPP); 1088 __ LoadFieldFromOffset(TMP, R0, Object::tags_offset(), kNoPP);
1089 __ tsti(TMP, 1 << RawObject::kRememberedBit); 1089 __ tsti(TMP, Immediate(1 << RawObject::kRememberedBit));
1090 __ b(&add_to_buffer, EQ); 1090 __ b(&add_to_buffer, EQ);
1091 __ ret(); 1091 __ ret();
1092 1092
1093 __ Bind(&add_to_buffer); 1093 __ Bind(&add_to_buffer);
1094 // Save values being destroyed. 1094 // Save values being destroyed.
1095 __ Push(R1); 1095 __ Push(R1);
1096 __ Push(R2); 1096 __ Push(R2);
1097 __ Push(R3); 1097 __ Push(R3);
1098 1098
1099 __ orri(R2, TMP, 1 << RawObject::kRememberedBit); 1099 __ orri(R2, TMP, Immediate(1 << RawObject::kRememberedBit));
1100 __ StoreFieldToOffset(R2, R0, Object::tags_offset(), kNoPP); 1100 __ StoreFieldToOffset(R2, R0, Object::tags_offset(), kNoPP);
1101 1101
1102 // Load the isolate. 1102 // Load the isolate.
1103 // Spilled: R1, R2, R3. 1103 // Spilled: R1, R2, R3.
1104 // R0: address being stored. 1104 // R0: address being stored.
1105 __ LoadImmediate(R1, Isolate::CurrentAddress(), kNoPP); 1105 __ LoadImmediate(R1, Isolate::CurrentAddress(), kNoPP);
1106 1106
1107 // Load the StoreBuffer block out of the isolate. Then load top_ out of the 1107 // Load the StoreBuffer block out of the isolate. Then load top_ out of the
1108 // StoreBufferBlock and add the address to the pointers_. 1108 // StoreBufferBlock and add the address to the pointers_.
1109 // R1: isolate. 1109 // R1: isolate.
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 Token::Kind kind, 1355 Token::Kind kind,
1356 intptr_t num_args, 1356 intptr_t num_args,
1357 Label* not_smi_or_overflow) { 1357 Label* not_smi_or_overflow) {
1358 if (FLAG_throw_on_javascript_int_overflow) { 1358 if (FLAG_throw_on_javascript_int_overflow) {
1359 // The overflow check is more complex than implemented below. 1359 // The overflow check is more complex than implemented below.
1360 return; 1360 return;
1361 } 1361 }
1362 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right. 1362 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right.
1363 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left. 1363 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left.
1364 __ orr(TMP, R0, Operand(R1)); 1364 __ orr(TMP, R0, Operand(R1));
1365 __ tsti(TMP, kSmiTagMask); 1365 __ tsti(TMP, Immediate(kSmiTagMask));
1366 __ b(not_smi_or_overflow, NE); 1366 __ b(not_smi_or_overflow, NE);
1367 switch (kind) { 1367 switch (kind) {
1368 case Token::kADD: { 1368 case Token::kADD: {
1369 __ adds(R0, R1, Operand(R0)); // Adds. 1369 __ adds(R0, R1, Operand(R0)); // Adds.
1370 __ b(not_smi_or_overflow, VS); // Branch if overflow. 1370 __ b(not_smi_or_overflow, VS); // Branch if overflow.
1371 break; 1371 break;
1372 } 1372 }
1373 case Token::kSUB: { 1373 case Token::kSUB: {
1374 __ subs(R0, R1, Operand(R0)); // Subtract. 1374 __ subs(R0, R1, Operand(R0)); // Subtract.
1375 __ b(not_smi_or_overflow, VS); // Branch if overflow. 1375 __ b(not_smi_or_overflow, VS); // Branch if overflow.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 const RuntimeEntry& handle_ic_miss, 1432 const RuntimeEntry& handle_ic_miss,
1433 Token::Kind kind) { 1433 Token::Kind kind) {
1434 ASSERT(num_args > 0); 1434 ASSERT(num_args > 0);
1435 #if defined(DEBUG) 1435 #if defined(DEBUG)
1436 { Label ok; 1436 { Label ok;
1437 // Check that the IC data array has NumArgsTested() == num_args. 1437 // Check that the IC data array has NumArgsTested() == num_args.
1438 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1438 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1439 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, 1439 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag,
1440 kNoPP, kUnsignedWord); 1440 kNoPP, kUnsignedWord);
1441 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1441 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1442 __ andi(R6, R6, ICData::NumArgsTestedMask()); 1442 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask()));
1443 __ CompareImmediate(R6, num_args, kNoPP); 1443 __ CompareImmediate(R6, num_args, kNoPP);
1444 __ b(&ok, EQ); 1444 __ b(&ok, EQ);
1445 __ Stop("Incorrect stub for IC data"); 1445 __ Stop("Incorrect stub for IC data");
1446 __ Bind(&ok); 1446 __ Bind(&ok);
1447 } 1447 }
1448 #endif // DEBUG 1448 #endif // DEBUG
1449 1449
1450 // Check single stepping. 1450 // Check single stepping.
1451 Label stepping, done_stepping; 1451 Label stepping, done_stepping;
1452 __ LoadImmediate(R6, Isolate::CurrentAddress(), kNoPP); 1452 __ LoadImmediate(R6, Isolate::CurrentAddress(), kNoPP);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 1664
1665 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1665 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1666 GenerateUsageCounterIncrement(assembler, R6); 1666 GenerateUsageCounterIncrement(assembler, R6);
1667 #if defined(DEBUG) 1667 #if defined(DEBUG)
1668 { Label ok; 1668 { Label ok;
1669 // Check that the IC data array has NumArgsTested() == 0. 1669 // Check that the IC data array has NumArgsTested() == 0.
1670 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1670 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1671 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, 1671 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag,
1672 kNoPP, kUnsignedWord); 1672 kNoPP, kUnsignedWord);
1673 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1673 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1674 __ andi(R6, R6, ICData::NumArgsTestedMask()); 1674 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask()));
1675 __ CompareImmediate(R6, 0, kNoPP); 1675 __ CompareImmediate(R6, 0, kNoPP);
1676 __ b(&ok, EQ); 1676 __ b(&ok, EQ);
1677 __ Stop("Incorrect IC data for unoptimized static call"); 1677 __ Stop("Incorrect IC data for unoptimized static call");
1678 __ Bind(&ok); 1678 __ Bind(&ok);
1679 } 1679 }
1680 #endif // DEBUG 1680 #endif // DEBUG
1681 1681
1682 // Check single stepping. 1682 // Check single stepping.
1683 Label stepping, done_stepping; 1683 Label stepping, done_stepping;
1684 __ LoadImmediate(R6, Isolate::CurrentAddress(), kNoPP); 1684 __ LoadImmediate(R6, Isolate::CurrentAddress(), kNoPP);
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 // Return Zero condition flag set if equal. 1996 // Return Zero condition flag set if equal.
1997 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint 1997 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint
1998 // cannot contain a value that fits in Mint or Smi. 1998 // cannot contain a value that fits in Mint or Smi.
1999 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler, 1999 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
2000 const Register left, 2000 const Register left,
2001 const Register right, 2001 const Register right,
2002 const Register unused1, 2002 const Register unused1,
2003 const Register unused2) { 2003 const Register unused2) {
2004 Label reference_compare, done, check_mint, check_bigint; 2004 Label reference_compare, done, check_mint, check_bigint;
2005 // If any of the arguments is Smi do reference compare. 2005 // If any of the arguments is Smi do reference compare.
2006 __ tsti(left, kSmiTagMask); 2006 __ tsti(left, Immediate(kSmiTagMask));
2007 __ b(&reference_compare, EQ); 2007 __ b(&reference_compare, EQ);
2008 __ tsti(right, kSmiTagMask); 2008 __ tsti(right, Immediate(kSmiTagMask));
2009 __ b(&reference_compare, EQ); 2009 __ b(&reference_compare, EQ);
2010 2010
2011 // Value compare for two doubles. 2011 // Value compare for two doubles.
2012 __ CompareClassId(left, kDoubleCid, kNoPP); 2012 __ CompareClassId(left, kDoubleCid, kNoPP);
2013 __ b(&check_mint, NE); 2013 __ b(&check_mint, NE);
2014 __ CompareClassId(right, kDoubleCid, kNoPP); 2014 __ CompareClassId(right, kDoubleCid, kNoPP);
2015 __ b(&done, NE); 2015 __ b(&done, NE);
2016 2016
2017 // Double values bitwise compare. 2017 // Double values bitwise compare.
2018 __ LoadFieldFromOffset(left, left, Double::value_offset(), kNoPP); 2018 __ LoadFieldFromOffset(left, left, Double::value_offset(), kNoPP);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 const Register right = R0; 2093 const Register right = R0;
2094 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); 2094 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP);
2095 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); 2095 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP);
2096 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2096 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2097 __ ret(); 2097 __ ret();
2098 } 2098 }
2099 2099
2100 } // namespace dart 2100 } // namespace dart
2101 2101
2102 #endif // defined TARGET_ARCH_ARM64 2102 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698