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

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
« no previous file with comments | « runtime/vm/object_arm64_test.cc ('k') | runtime/vm/stub_code_mips.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) 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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. 669 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
670 // The newly allocated object is returned in R0. 670 // The newly allocated object is returned in R0.
671 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler, 671 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler,
672 uword* entry_patch_offset, uword* patch_code_pc_offset) { 672 uword* entry_patch_offset, uword* patch_code_pc_offset) {
673 *entry_patch_offset = assembler->CodeSize(); 673 *entry_patch_offset = assembler->CodeSize();
674 Label slow_case; 674 Label slow_case;
675 // Compute the size to be allocated, it is based on the array length 675 // Compute the size to be allocated, it is based on the array length
676 // and is computed as: 676 // and is computed as:
677 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 677 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
678 // Assert that length is a Smi. 678 // Assert that length is a Smi.
679 __ tsti(R2, kSmiTagMask); 679 __ tsti(R2, Immediate(kSmiTagMask));
680 if (FLAG_use_slow_path) { 680 if (FLAG_use_slow_path) {
681 __ b(&slow_case); 681 __ b(&slow_case);
682 } else { 682 } else {
683 __ b(&slow_case, NE); 683 __ b(&slow_case, NE);
684 } 684 }
685 __ cmp(R2, Operand(0)); 685 __ cmp(R2, Operand(0));
686 __ b(&slow_case, LT); 686 __ b(&slow_case, LT);
687 687
688 Isolate* isolate = Isolate::Current(); 688 Isolate* isolate = Isolate::Current();
689 Heap* heap = isolate->heap(); 689 Heap* heap = isolate->heap();
690 const intptr_t cid = kArrayCid; 690 const intptr_t cid = kArrayCid;
691 Heap::Space space = heap->SpaceForAllocation(cid); 691 Heap::Space space = heap->SpaceForAllocation(cid);
692 const uword top_address = heap->TopAddress(space); 692 const uword top_address = heap->TopAddress(space);
693 __ LoadImmediate(R8, top_address, kNoPP); 693 __ LoadImmediate(R8, top_address, kNoPP);
694 const uword end_address = heap->EndAddress(space); 694 const uword end_address = heap->EndAddress(space);
695 ASSERT(top_address < end_address); 695 ASSERT(top_address < end_address);
696 const uword top_offset = 0; 696 const uword top_offset = 0;
697 const uword end_offset = end_address - top_address; 697 const uword end_offset = end_address - top_address;
698 698
699 // Calculate and align allocation size. 699 // Calculate and align allocation size.
700 // Load new object start and calculate next object start. 700 // Load new object start and calculate next object start.
701 // R1: array element type. 701 // R1: array element type.
702 // R2: array length as Smi. 702 // R2: array length as Smi.
703 // R8: points to new space object. 703 // R8: points to new space object.
704 __ LoadFromOffset(R0, R8, top_offset, kNoPP); 704 __ LoadFromOffset(R0, R8, top_offset, kNoPP);
705 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 705 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
706 __ LoadImmediate(R3, fixed_size, kNoPP); 706 __ LoadImmediate(R3, fixed_size, kNoPP);
707 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi. 707 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi.
708 ASSERT(kSmiTagShift == 1); 708 ASSERT(kSmiTagShift == 1);
709 __ andi(R3, R3, ~(kObjectAlignment - 1)); 709 __ andi(R3, R3, Immediate(~(kObjectAlignment - 1)));
710 __ adds(R7, R3, Operand(R0)); 710 __ adds(R7, R3, Operand(R0));
711 __ b(&slow_case, VS); 711 __ b(&slow_case, VS);
712 712
713 // Check if the allocation fits into the remaining space. 713 // Check if the allocation fits into the remaining space.
714 // R0: potential new object start. 714 // R0: potential new object start.
715 // R1: array element type. 715 // R1: array element type.
716 // R2: array length as Smi. 716 // R2: array length as Smi.
717 // R3: array size. 717 // R3: array size.
718 // R7: potential next object start. 718 // R7: potential next object start.
719 // R8: points to new space object. 719 // R8: points to new space object.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 992 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
993 if (FLAG_inline_alloc) { 993 if (FLAG_inline_alloc) {
994 Label slow_case; 994 Label slow_case;
995 Heap* heap = Isolate::Current()->heap(); 995 Heap* heap = Isolate::Current()->heap();
996 // First compute the rounded instance size. 996 // First compute the rounded instance size.
997 // R1: number of context variables. 997 // R1: number of context variables.
998 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; 998 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1;
999 __ LoadImmediate(R2, fixed_size, kNoPP); 999 __ LoadImmediate(R2, fixed_size, kNoPP);
1000 __ add(R2, R2, Operand(R1, LSL, 3)); 1000 __ add(R2, R2, Operand(R1, LSL, 3));
1001 ASSERT(kSmiTagShift == 1); 1001 ASSERT(kSmiTagShift == 1);
1002 __ andi(R2, R2, ~(kObjectAlignment - 1)); 1002 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1)));
1003 1003
1004 // Now allocate the object. 1004 // Now allocate the object.
1005 // R1: number of context variables. 1005 // R1: number of context variables.
1006 // R2: object size. 1006 // R2: object size.
1007 const intptr_t cid = kContextCid; 1007 const intptr_t cid = kContextCid;
1008 Heap::Space space = heap->SpaceForAllocation(cid); 1008 Heap::Space space = heap->SpaceForAllocation(cid);
1009 __ LoadImmediate(R5, heap->TopAddress(space), kNoPP); 1009 __ LoadImmediate(R5, heap->TopAddress(space), kNoPP);
1010 __ ldr(R0, Address(R5)); 1010 __ ldr(R0, Address(R5));
1011 __ add(R3, R2, Operand(R0)); 1011 __ add(R3, R2, Operand(R0));
1012 // Check if the allocation fits into the remaining space. 1012 // Check if the allocation fits into the remaining space.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); 1110 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate);
1111 1111
1112 // Helper stub to implement Assembler::StoreIntoObject. 1112 // Helper stub to implement Assembler::StoreIntoObject.
1113 // Input parameters: 1113 // Input parameters:
1114 // R0: Address being stored 1114 // R0: Address being stored
1115 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { 1115 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
1116 Label add_to_buffer; 1116 Label add_to_buffer;
1117 // Check whether this object has already been remembered. Skip adding to the 1117 // Check whether this object has already been remembered. Skip adding to the
1118 // store buffer if the object is in the store buffer already. 1118 // store buffer if the object is in the store buffer already.
1119 __ LoadFieldFromOffset(TMP, R0, Object::tags_offset(), kNoPP); 1119 __ LoadFieldFromOffset(TMP, R0, Object::tags_offset(), kNoPP);
1120 __ tsti(TMP, 1 << RawObject::kRememberedBit); 1120 __ tsti(TMP, Immediate(1 << RawObject::kRememberedBit));
1121 __ b(&add_to_buffer, EQ); 1121 __ b(&add_to_buffer, EQ);
1122 __ ret(); 1122 __ ret();
1123 1123
1124 __ Bind(&add_to_buffer); 1124 __ Bind(&add_to_buffer);
1125 // Save values being destroyed. 1125 // Save values being destroyed.
1126 __ Push(R1); 1126 __ Push(R1);
1127 __ Push(R2); 1127 __ Push(R2);
1128 __ Push(R3); 1128 __ Push(R3);
1129 1129
1130 __ orri(R2, TMP, 1 << RawObject::kRememberedBit); 1130 __ orri(R2, TMP, Immediate(1 << RawObject::kRememberedBit));
1131 __ StoreFieldToOffset(R2, R0, Object::tags_offset(), kNoPP); 1131 __ StoreFieldToOffset(R2, R0, Object::tags_offset(), kNoPP);
1132 1132
1133 // Load the isolate. 1133 // Load the isolate.
1134 // Spilled: R1, R2, R3. 1134 // Spilled: R1, R2, R3.
1135 // R0: address being stored. 1135 // R0: address being stored.
1136 __ LoadIsolate(R1, kNoPP); 1136 __ LoadIsolate(R1, kNoPP);
1137 1137
1138 // Load the StoreBuffer block out of the isolate. Then load top_ out of the 1138 // Load the StoreBuffer block out of the isolate. Then load top_ out of the
1139 // StoreBufferBlock and add the address to the pointers_. 1139 // StoreBufferBlock and add the address to the pointers_.
1140 // R1: isolate. 1140 // R1: isolate.
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 Token::Kind kind, 1386 Token::Kind kind,
1387 intptr_t num_args, 1387 intptr_t num_args,
1388 Label* not_smi_or_overflow) { 1388 Label* not_smi_or_overflow) {
1389 if (FLAG_throw_on_javascript_int_overflow) { 1389 if (FLAG_throw_on_javascript_int_overflow) {
1390 // The overflow check is more complex than implemented below. 1390 // The overflow check is more complex than implemented below.
1391 return; 1391 return;
1392 } 1392 }
1393 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right. 1393 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Right.
1394 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left. 1394 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Left.
1395 __ orr(TMP, R0, Operand(R1)); 1395 __ orr(TMP, R0, Operand(R1));
1396 __ tsti(TMP, kSmiTagMask); 1396 __ tsti(TMP, Immediate(kSmiTagMask));
1397 __ b(not_smi_or_overflow, NE); 1397 __ b(not_smi_or_overflow, NE);
1398 switch (kind) { 1398 switch (kind) {
1399 case Token::kADD: { 1399 case Token::kADD: {
1400 __ adds(R0, R1, Operand(R0)); // Adds. 1400 __ adds(R0, R1, Operand(R0)); // Adds.
1401 __ b(not_smi_or_overflow, VS); // Branch if overflow. 1401 __ b(not_smi_or_overflow, VS); // Branch if overflow.
1402 break; 1402 break;
1403 } 1403 }
1404 case Token::kSUB: { 1404 case Token::kSUB: {
1405 __ subs(R0, R1, Operand(R0)); // Subtract. 1405 __ subs(R0, R1, Operand(R0)); // Subtract.
1406 __ b(not_smi_or_overflow, VS); // Branch if overflow. 1406 __ b(not_smi_or_overflow, VS); // Branch if overflow.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 const RuntimeEntry& handle_ic_miss, 1463 const RuntimeEntry& handle_ic_miss,
1464 Token::Kind kind) { 1464 Token::Kind kind) {
1465 ASSERT(num_args > 0); 1465 ASSERT(num_args > 0);
1466 #if defined(DEBUG) 1466 #if defined(DEBUG)
1467 { Label ok; 1467 { Label ok;
1468 // Check that the IC data array has NumArgsTested() == num_args. 1468 // Check that the IC data array has NumArgsTested() == num_args.
1469 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1469 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1470 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, 1470 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag,
1471 kNoPP, kUnsignedWord); 1471 kNoPP, kUnsignedWord);
1472 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1472 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1473 __ andi(R6, R6, ICData::NumArgsTestedMask()); 1473 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask()));
1474 __ CompareImmediate(R6, num_args, kNoPP); 1474 __ CompareImmediate(R6, num_args, kNoPP);
1475 __ b(&ok, EQ); 1475 __ b(&ok, EQ);
1476 __ Stop("Incorrect stub for IC data"); 1476 __ Stop("Incorrect stub for IC data");
1477 __ Bind(&ok); 1477 __ Bind(&ok);
1478 } 1478 }
1479 #endif // DEBUG 1479 #endif // DEBUG
1480 1480
1481 // Check single stepping. 1481 // Check single stepping.
1482 Label stepping, done_stepping; 1482 Label stepping, done_stepping;
1483 __ LoadIsolate(R6, kNoPP); 1483 __ LoadIsolate(R6, kNoPP);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 1695
1696 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1696 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1697 GenerateUsageCounterIncrement(assembler, R6); 1697 GenerateUsageCounterIncrement(assembler, R6);
1698 #if defined(DEBUG) 1698 #if defined(DEBUG)
1699 { Label ok; 1699 { Label ok;
1700 // Check that the IC data array has NumArgsTested() == 0. 1700 // Check that the IC data array has NumArgsTested() == 0.
1701 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1701 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1702 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag, 1702 __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag,
1703 kNoPP, kUnsignedWord); 1703 kNoPP, kUnsignedWord);
1704 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1704 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1705 __ andi(R6, R6, ICData::NumArgsTestedMask()); 1705 __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask()));
1706 __ CompareImmediate(R6, 0, kNoPP); 1706 __ CompareImmediate(R6, 0, kNoPP);
1707 __ b(&ok, EQ); 1707 __ b(&ok, EQ);
1708 __ Stop("Incorrect IC data for unoptimized static call"); 1708 __ Stop("Incorrect IC data for unoptimized static call");
1709 __ Bind(&ok); 1709 __ Bind(&ok);
1710 } 1710 }
1711 #endif // DEBUG 1711 #endif // DEBUG
1712 1712
1713 // Check single stepping. 1713 // Check single stepping.
1714 Label stepping, done_stepping; 1714 Label stepping, done_stepping;
1715 __ LoadIsolate(R6, kNoPP); 1715 __ LoadIsolate(R6, kNoPP);
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 // Return Zero condition flag set if equal. 2027 // Return Zero condition flag set if equal.
2028 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint 2028 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint
2029 // cannot contain a value that fits in Mint or Smi. 2029 // cannot contain a value that fits in Mint or Smi.
2030 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler, 2030 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
2031 const Register left, 2031 const Register left,
2032 const Register right, 2032 const Register right,
2033 const Register unused1, 2033 const Register unused1,
2034 const Register unused2) { 2034 const Register unused2) {
2035 Label reference_compare, done, check_mint, check_bigint; 2035 Label reference_compare, done, check_mint, check_bigint;
2036 // If any of the arguments is Smi do reference compare. 2036 // If any of the arguments is Smi do reference compare.
2037 __ tsti(left, kSmiTagMask); 2037 __ tsti(left, Immediate(kSmiTagMask));
2038 __ b(&reference_compare, EQ); 2038 __ b(&reference_compare, EQ);
2039 __ tsti(right, kSmiTagMask); 2039 __ tsti(right, Immediate(kSmiTagMask));
2040 __ b(&reference_compare, EQ); 2040 __ b(&reference_compare, EQ);
2041 2041
2042 // Value compare for two doubles. 2042 // Value compare for two doubles.
2043 __ CompareClassId(left, kDoubleCid, kNoPP); 2043 __ CompareClassId(left, kDoubleCid, kNoPP);
2044 __ b(&check_mint, NE); 2044 __ b(&check_mint, NE);
2045 __ CompareClassId(right, kDoubleCid, kNoPP); 2045 __ CompareClassId(right, kDoubleCid, kNoPP);
2046 __ b(&done, NE); 2046 __ b(&done, NE);
2047 2047
2048 // Double values bitwise compare. 2048 // Double values bitwise compare.
2049 __ LoadFieldFromOffset(left, left, Double::value_offset(), kNoPP); 2049 __ LoadFieldFromOffset(left, left, Double::value_offset(), kNoPP);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2124 const Register right = R0; 2124 const Register right = R0;
2125 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); 2125 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP);
2126 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); 2126 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP);
2127 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2127 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2128 __ ret(); 2128 __ ret();
2129 } 2129 }
2130 2130
2131 } // namespace dart 2131 } // namespace dart
2132 2132
2133 #endif // defined TARGET_ARCH_ARM64 2133 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/object_arm64_test.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698