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

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

Issue 1174173007: Expand the class id to 32 bits and size field to 16 bits on 64-bit platforms. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_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) 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" // Needed here to get TARGET_ARCH_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 return LocationSummary::Make(zone, 924 return LocationSummary::Make(zone,
925 kNumInputs, 925 kNumInputs,
926 Location::RequiresRegister(), 926 Location::RequiresRegister(),
927 LocationSummary::kNoCall); 927 LocationSummary::kNoCall);
928 } 928 }
929 929
930 930
931 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 931 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
932 const Register object = locs()->in(0).reg(); 932 const Register object = locs()->in(0).reg();
933 const Register result = locs()->out(0).reg(); 933 const Register result = locs()->out(0).reg();
934 static const intptr_t kSmiCidSource = kSmiCid << RawObject::kClassIdTagPos; 934 static const intptr_t kSmiCidSource =
935 static_cast<intptr_t>(kSmiCid) << RawObject::kClassIdTagPos;
935 936
936 __ LoadImmediate(TMP, reinterpret_cast<int64_t>(&kSmiCidSource) + 1, PP); 937 __ LoadImmediate(TMP, reinterpret_cast<int64_t>(&kSmiCidSource) + 1, PP);
937 __ tsti(object, Immediate(kSmiTagMask)); 938 __ tsti(object, Immediate(kSmiTagMask));
938 __ csel(TMP, TMP, object, EQ); 939 __ csel(TMP, TMP, object, EQ);
939 __ LoadClassId(result, TMP, PP); 940 __ LoadClassId(result, TMP, PP);
940 __ SmiTag(result); 941 __ SmiTag(result);
941 } 942 }
942 943
943 944
944 CompileType LoadIndexedInstr::ComputeType() const { 945 CompileType LoadIndexedInstr::ComputeType() const {
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 1428
1428 for (intptr_t i = 0; i < num_temps; i++) { 1429 for (intptr_t i = 0; i < num_temps; i++) {
1429 summary->set_temp(i, Location::RequiresRegister()); 1430 summary->set_temp(i, Location::RequiresRegister());
1430 } 1431 }
1431 1432
1432 return summary; 1433 return summary;
1433 } 1434 }
1434 1435
1435 1436
1436 void GuardFieldClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1437 void GuardFieldClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1438 ASSERT(sizeof(classid_t) == kInt32Size);
1437 const intptr_t value_cid = value()->Type()->ToCid(); 1439 const intptr_t value_cid = value()->Type()->ToCid();
1438 const intptr_t field_cid = field().guarded_cid(); 1440 const intptr_t field_cid = field().guarded_cid();
1439 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid; 1441 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
1440 1442
1441 if (field_cid == kDynamicCid) { 1443 if (field_cid == kDynamicCid) {
1442 ASSERT(!compiler->is_optimizing()); 1444 ASSERT(!compiler->is_optimizing());
1443 return; // Nothing to emit. 1445 return; // Nothing to emit.
1444 } 1446 }
1445 1447
1446 const bool emit_full_guard = 1448 const bool emit_full_guard =
(...skipping 16 matching lines...) Expand all
1463 1465
1464 Label* deopt = compiler->is_optimizing() ? 1466 Label* deopt = compiler->is_optimizing() ?
1465 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; 1467 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL;
1466 1468
1467 Label* fail = (deopt != NULL) ? deopt : &fail_label; 1469 Label* fail = (deopt != NULL) ? deopt : &fail_label;
1468 1470
1469 if (emit_full_guard) { 1471 if (emit_full_guard) {
1470 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); 1472 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP);
1471 1473
1472 FieldAddress field_cid_operand( 1474 FieldAddress field_cid_operand(
1473 field_reg, Field::guarded_cid_offset(), kUnsignedHalfword); 1475 field_reg, Field::guarded_cid_offset(), kUnsignedWord);
1474 FieldAddress field_nullability_operand( 1476 FieldAddress field_nullability_operand(
1475 field_reg, Field::is_nullable_offset(), kUnsignedHalfword); 1477 field_reg, Field::is_nullable_offset(), kUnsignedWord);
1476 1478
1477 if (value_cid == kDynamicCid) { 1479 if (value_cid == kDynamicCid) {
1478 LoadValueCid(compiler, value_cid_reg, value_reg); 1480 LoadValueCid(compiler, value_cid_reg, value_reg);
1479 Label skip_length_check; 1481 Label skip_length_check;
1480 __ ldr(TMP, field_cid_operand, kUnsignedHalfword); 1482 __ ldr(TMP, field_cid_operand, kUnsignedWord);
1481 __ CompareRegisters(value_cid_reg, TMP); 1483 __ CompareRegisters(value_cid_reg, TMP);
1482 __ b(&ok, EQ); 1484 __ b(&ok, EQ);
1483 __ ldr(TMP, field_nullability_operand, kUnsignedHalfword); 1485 __ ldr(TMP, field_nullability_operand, kUnsignedWord);
1484 __ CompareRegisters(value_cid_reg, TMP); 1486 __ CompareRegisters(value_cid_reg, TMP);
1485 } else if (value_cid == kNullCid) { 1487 } else if (value_cid == kNullCid) {
1486 __ ldr(value_cid_reg, field_nullability_operand, kUnsignedHalfword); 1488 __ ldr(value_cid_reg, field_nullability_operand, kUnsignedWord);
1487 __ CompareImmediate(value_cid_reg, value_cid, PP); 1489 __ CompareImmediate(value_cid_reg, value_cid, PP);
1488 } else { 1490 } else {
1489 Label skip_length_check; 1491 Label skip_length_check;
1490 __ ldr(value_cid_reg, field_cid_operand, kUnsignedHalfword); 1492 __ ldr(value_cid_reg, field_cid_operand, kUnsignedWord);
1491 __ CompareImmediate(value_cid_reg, value_cid, PP); 1493 __ CompareImmediate(value_cid_reg, value_cid, PP);
1492 } 1494 }
1493 __ b(&ok, EQ); 1495 __ b(&ok, EQ);
1494 1496
1495 // Check if the tracked state of the guarded field can be initialized 1497 // Check if the tracked state of the guarded field can be initialized
1496 // inline. If the field needs length check we fall through to runtime 1498 // inline. If the field needs length check we fall through to runtime
1497 // which is responsible for computing offset of the length field 1499 // which is responsible for computing offset of the length field
1498 // based on the class id. 1500 // based on the class id.
1499 // Length guard will be emitted separately when needed via GuardFieldLength 1501 // Length guard will be emitted separately when needed via GuardFieldLength
1500 // instruction after GuardFieldClass. 1502 // instruction after GuardFieldClass.
1501 if (!field().needs_length_check()) { 1503 if (!field().needs_length_check()) {
1502 // Uninitialized field can be handled inline. Check if the 1504 // Uninitialized field can be handled inline. Check if the
1503 // field is still unitialized. 1505 // field is still unitialized.
1504 __ ldr(TMP, field_cid_operand, kUnsignedHalfword); 1506 __ ldr(TMP, field_cid_operand, kUnsignedWord);
1505 __ CompareImmediate(TMP, kIllegalCid, PP); 1507 __ CompareImmediate(TMP, kIllegalCid, PP);
1506 __ b(fail, NE); 1508 __ b(fail, NE);
1507 1509
1508 if (value_cid == kDynamicCid) { 1510 if (value_cid == kDynamicCid) {
1509 __ str(value_cid_reg, field_cid_operand, kUnsignedHalfword); 1511 __ str(value_cid_reg, field_cid_operand, kUnsignedWord);
1510 __ str(value_cid_reg, field_nullability_operand, kUnsignedHalfword); 1512 __ str(value_cid_reg, field_nullability_operand, kUnsignedWord);
1511 } else { 1513 } else {
1512 __ LoadImmediate(TMP, value_cid, PP); 1514 __ LoadImmediate(TMP, value_cid, PP);
1513 __ str(TMP, field_cid_operand, kUnsignedHalfword); 1515 __ str(TMP, field_cid_operand, kUnsignedWord);
1514 __ str(TMP, field_nullability_operand, kUnsignedHalfword); 1516 __ str(TMP, field_nullability_operand, kUnsignedWord);
1515 } 1517 }
1516 1518
1517 if (deopt == NULL) { 1519 if (deopt == NULL) {
1518 ASSERT(!compiler->is_optimizing()); 1520 ASSERT(!compiler->is_optimizing());
1519 __ b(&ok); 1521 __ b(&ok);
1520 } 1522 }
1521 } 1523 }
1522 1524
1523 if (deopt == NULL) { 1525 if (deopt == NULL) {
1524 ASSERT(!compiler->is_optimizing()); 1526 ASSERT(!compiler->is_optimizing());
1525 __ Bind(fail); 1527 __ Bind(fail);
1526 1528
1527 __ LoadFieldFromOffset( 1529 __ LoadFieldFromOffset(
1528 TMP, field_reg, Field::guarded_cid_offset(), PP, kUnsignedHalfword); 1530 TMP, field_reg, Field::guarded_cid_offset(), PP, kUnsignedWord);
1529 __ CompareImmediate(TMP, kDynamicCid, PP); 1531 __ CompareImmediate(TMP, kDynamicCid, PP);
1530 __ b(&ok, EQ); 1532 __ b(&ok, EQ);
1531 1533
1532 __ Push(field_reg); 1534 __ Push(field_reg);
1533 __ Push(value_reg); 1535 __ Push(value_reg);
1534 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); 1536 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2);
1535 __ Drop(2); // Drop the field and the value. 1537 __ Drop(2); // Drop the field and the value.
1536 } 1538 }
1537 } else { 1539 } else {
1538 ASSERT(compiler->is_optimizing()); 1540 ASSERT(compiler->is_optimizing());
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 } else { 1769 } else {
1768 summary->set_in(1, ShouldEmitStoreBarrier() 1770 summary->set_in(1, ShouldEmitStoreBarrier()
1769 ? Location::WritableRegister() 1771 ? Location::WritableRegister()
1770 : Location::RegisterOrConstant(value())); 1772 : Location::RegisterOrConstant(value()));
1771 } 1773 }
1772 return summary; 1774 return summary;
1773 } 1775 }
1774 1776
1775 1777
1776 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1778 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1779 ASSERT(sizeof(classid_t) == kInt32Size);
1777 Label skip_store; 1780 Label skip_store;
1778 1781
1779 const Register instance_reg = locs()->in(0).reg(); 1782 const Register instance_reg = locs()->in(0).reg();
1780 1783
1781 if (IsUnboxedStore() && compiler->is_optimizing()) { 1784 if (IsUnboxedStore() && compiler->is_optimizing()) {
1782 const VRegister value = locs()->in(1).fpu_reg(); 1785 const VRegister value = locs()->in(1).fpu_reg();
1783 const Register temp = locs()->temp(0).reg(); 1786 const Register temp = locs()->temp(0).reg();
1784 const Register temp2 = locs()->temp(1).reg(); 1787 const Register temp2 = locs()->temp(1).reg();
1785 const intptr_t cid = field().UnboxedFieldCid(); 1788 const intptr_t cid = field().UnboxedFieldCid();
1786 1789
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 } 1841 }
1839 1842
1840 Label store_pointer; 1843 Label store_pointer;
1841 Label store_double; 1844 Label store_double;
1842 Label store_float32x4; 1845 Label store_float32x4;
1843 Label store_float64x2; 1846 Label store_float64x2;
1844 1847
1845 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP); 1848 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP);
1846 1849
1847 __ LoadFieldFromOffset(temp2, temp, Field::is_nullable_offset(), PP, 1850 __ LoadFieldFromOffset(temp2, temp, Field::is_nullable_offset(), PP,
1848 kUnsignedHalfword); 1851 kUnsignedWord);
1849 __ CompareImmediate(temp2, kNullCid, PP); 1852 __ CompareImmediate(temp2, kNullCid, PP);
1850 __ b(&store_pointer, EQ); 1853 __ b(&store_pointer, EQ);
1851 1854
1852 __ LoadFromOffset( 1855 __ LoadFromOffset(
1853 temp2, temp, Field::kind_bits_offset() - kHeapObjectTag, 1856 temp2, temp, Field::kind_bits_offset() - kHeapObjectTag,
1854 PP, kUnsignedByte); 1857 PP, kUnsignedByte);
1855 __ tsti(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); 1858 __ tsti(temp2, Immediate(1 << Field::kUnboxingCandidateBit));
1856 __ b(&store_pointer, EQ); 1859 __ b(&store_pointer, EQ);
1857 1860
1858 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP, 1861 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP,
1859 kUnsignedHalfword); 1862 kUnsignedWord);
1860 __ CompareImmediate(temp2, kDoubleCid, PP); 1863 __ CompareImmediate(temp2, kDoubleCid, PP);
1861 __ b(&store_double, EQ); 1864 __ b(&store_double, EQ);
1862 1865
1863 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP, 1866 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP,
1864 kUnsignedHalfword); 1867 kUnsignedWord);
1865 __ CompareImmediate(temp2, kFloat32x4Cid, PP); 1868 __ CompareImmediate(temp2, kFloat32x4Cid, PP);
1866 __ b(&store_float32x4, EQ); 1869 __ b(&store_float32x4, EQ);
1867 1870
1868 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP, 1871 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP,
1869 kUnsignedHalfword); 1872 kUnsignedWord);
1870 __ CompareImmediate(temp2, kFloat64x2Cid, PP); 1873 __ CompareImmediate(temp2, kFloat64x2Cid, PP);
1871 __ b(&store_float64x2, EQ); 1874 __ b(&store_float64x2, EQ);
1872 1875
1873 // Fall through. 1876 // Fall through.
1874 __ b(&store_pointer); 1877 __ b(&store_pointer);
1875 1878
1876 if (!compiler->is_optimizing()) { 1879 if (!compiler->is_optimizing()) {
1877 locs()->live_registers()->Add(locs()->in(0)); 1880 locs()->live_registers()->Add(locs()->in(0));
1878 locs()->live_registers()->Add(locs()->in(1)); 1881 locs()->live_registers()->Add(locs()->in(1));
1879 } 1882 }
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2158 locs->set_temp(0, Location::RequiresRegister()); 2161 locs->set_temp(0, Location::RequiresRegister());
2159 } else if (IsPotentialUnboxedLoad()) { 2162 } else if (IsPotentialUnboxedLoad()) {
2160 locs->set_temp(0, Location::RequiresRegister()); 2163 locs->set_temp(0, Location::RequiresRegister());
2161 } 2164 }
2162 locs->set_out(0, Location::RequiresRegister()); 2165 locs->set_out(0, Location::RequiresRegister());
2163 return locs; 2166 return locs;
2164 } 2167 }
2165 2168
2166 2169
2167 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2170 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2171 ASSERT(sizeof(classid_t) == kInt32Size);
2168 const Register instance_reg = locs()->in(0).reg(); 2172 const Register instance_reg = locs()->in(0).reg();
2169 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2173 if (IsUnboxedLoad() && compiler->is_optimizing()) {
2170 const VRegister result = locs()->out(0).fpu_reg(); 2174 const VRegister result = locs()->out(0).fpu_reg();
2171 const Register temp = locs()->temp(0).reg(); 2175 const Register temp = locs()->temp(0).reg();
2172 __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes(), PP); 2176 __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes(), PP);
2173 const intptr_t cid = field()->UnboxedFieldCid(); 2177 const intptr_t cid = field()->UnboxedFieldCid();
2174 switch (cid) { 2178 switch (cid) {
2175 case kDoubleCid: 2179 case kDoubleCid:
2176 __ Comment("UnboxedDoubleLoadFieldInstr"); 2180 __ Comment("UnboxedDoubleLoadFieldInstr");
2177 __ LoadDFieldFromOffset(result, temp, Double::value_offset(), PP); 2181 __ LoadDFieldFromOffset(result, temp, Double::value_offset(), PP);
(...skipping 16 matching lines...) Expand all
2194 const Register temp = locs()->temp(0).reg(); 2198 const Register temp = locs()->temp(0).reg();
2195 2199
2196 Label load_pointer; 2200 Label load_pointer;
2197 Label load_double; 2201 Label load_double;
2198 Label load_float32x4; 2202 Label load_float32x4;
2199 Label load_float64x2; 2203 Label load_float64x2;
2200 2204
2201 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()), PP); 2205 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()), PP);
2202 2206
2203 FieldAddress field_cid_operand( 2207 FieldAddress field_cid_operand(
2204 result_reg, Field::guarded_cid_offset(), kUnsignedHalfword); 2208 result_reg, Field::guarded_cid_offset(), kUnsignedWord);
2205 FieldAddress field_nullability_operand( 2209 FieldAddress field_nullability_operand(
2206 result_reg, Field::is_nullable_offset(), kUnsignedHalfword); 2210 result_reg, Field::is_nullable_offset(), kUnsignedWord);
2207 2211
2208 __ ldr(temp, field_nullability_operand, kUnsignedHalfword); 2212 __ ldr(temp, field_nullability_operand, kUnsignedWord);
2209 __ CompareImmediate(temp, kNullCid, PP); 2213 __ CompareImmediate(temp, kNullCid, PP);
2210 __ b(&load_pointer, EQ); 2214 __ b(&load_pointer, EQ);
2211 2215
2212 __ ldr(temp, field_cid_operand, kUnsignedHalfword); 2216 __ ldr(temp, field_cid_operand, kUnsignedWord);
2213 __ CompareImmediate(temp, kDoubleCid, PP); 2217 __ CompareImmediate(temp, kDoubleCid, PP);
2214 __ b(&load_double, EQ); 2218 __ b(&load_double, EQ);
2215 2219
2216 __ ldr(temp, field_cid_operand, kUnsignedHalfword); 2220 __ ldr(temp, field_cid_operand, kUnsignedWord);
2217 __ CompareImmediate(temp, kFloat32x4Cid, PP); 2221 __ CompareImmediate(temp, kFloat32x4Cid, PP);
2218 __ b(&load_float32x4, EQ); 2222 __ b(&load_float32x4, EQ);
2219 2223
2220 __ ldr(temp, field_cid_operand, kUnsignedHalfword); 2224 __ ldr(temp, field_cid_operand, kUnsignedWord);
2221 __ CompareImmediate(temp, kFloat64x2Cid, PP); 2225 __ CompareImmediate(temp, kFloat64x2Cid, PP);
2222 __ b(&load_float64x2, EQ); 2226 __ b(&load_float64x2, EQ);
2223 2227
2224 // Fall through. 2228 // Fall through.
2225 __ b(&load_pointer); 2229 __ b(&load_pointer);
2226 2230
2227 if (!compiler->is_optimizing()) { 2231 if (!compiler->is_optimizing()) {
2228 locs()->live_registers()->Add(locs()->in(0)); 2232 locs()->live_registers()->Add(locs()->in(0));
2229 } 2233 }
2230 2234
(...skipping 3426 matching lines...) Expand 10 before | Expand all | Expand 10 after
5657 1, 5661 1,
5658 locs()); 5662 locs());
5659 __ Drop(1); 5663 __ Drop(1);
5660 __ Pop(result); 5664 __ Pop(result);
5661 } 5665 }
5662 5666
5663 5667
5664 } // namespace dart 5668 } // namespace dart
5665 5669
5666 #endif // defined TARGET_ARCH_ARM64 5670 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698