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

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

Issue 22825023: Uses an object pool on x64 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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) 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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; 89 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
90 ASSERT(fp_sp_dist <= 0); 90 ASSERT(fp_sp_dist <= 0);
91 __ movq(RDI, RSP); 91 __ movq(RDI, RSP);
92 __ subq(RDI, RBP); 92 __ subq(RDI, RBP);
93 __ cmpq(RDI, Immediate(fp_sp_dist)); 93 __ cmpq(RDI, Immediate(fp_sp_dist));
94 __ j(EQUAL, &done, Assembler::kNearJump); 94 __ j(EQUAL, &done, Assembler::kNearJump);
95 __ int3(); 95 __ int3();
96 __ Bind(&done); 96 __ Bind(&done);
97 } 97 }
98 #endif 98 #endif
99 __ LeaveFrame();
100 __ ret();
101 99
102 // Generate 8 bytes of NOPs so that the debugger can patch the 100 __ ReturnPatchable();
103 // return pattern with a call to the debug stub.
104 // Note that the nop(8) byte pattern is not recognized by the debugger.
105 __ nop(1);
106 __ nop(1);
107 __ nop(1);
108 __ nop(1);
109 __ nop(1);
110 __ nop(1);
111 __ nop(1);
112 __ nop(1);
113 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 101 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
114 Isolate::kNoDeoptId, 102 Isolate::kNoDeoptId,
115 token_pos()); 103 token_pos());
116 } 104 }
117 105
118 106
119 static Condition NegateCondition(Condition condition) { 107 static Condition NegateCondition(Condition condition) {
120 switch (condition) { 108 switch (condition) {
121 case EQUAL: return NOT_EQUAL; 109 case EQUAL: return NOT_EQUAL;
122 case NOT_EQUAL: return EQUAL; 110 case NOT_EQUAL: return EQUAL;
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 const ICData& original_ic_data) { 446 const ICData& original_ic_data) {
459 if (!compiler->is_optimizing()) { 447 if (!compiler->is_optimizing()) {
460 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 448 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
461 deopt_id, 449 deopt_id,
462 token_pos); 450 token_pos);
463 } 451 }
464 const int kNumberOfArguments = 2; 452 const int kNumberOfArguments = 2;
465 const Array& kNoArgumentNames = Object::null_array(); 453 const Array& kNoArgumentNames = Object::null_array();
466 const int kNumArgumentsChecked = 2; 454 const int kNumArgumentsChecked = 2;
467 455
468 const Immediate& raw_null =
469 Immediate(reinterpret_cast<intptr_t>(Object::null()));
470 Label check_identity; 456 Label check_identity;
471 __ cmpq(Address(RSP, 0 * kWordSize), raw_null); 457 __ LoadObject(TMP, Object::Handle());
458 __ cmpq(Address(RSP, 0 * kWordSize), TMP);
472 __ j(EQUAL, &check_identity); 459 __ j(EQUAL, &check_identity);
473 __ cmpq(Address(RSP, 1 * kWordSize), raw_null); 460 __ cmpq(Address(RSP, 1 * kWordSize), TMP);
474 __ j(EQUAL, &check_identity); 461 __ j(EQUAL, &check_identity);
475 462
476 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw()); 463 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw());
477 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 464 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
478 ASSERT(!original_ic_data.IsNull()); 465 ASSERT(!original_ic_data.IsNull());
479 if (original_ic_data.NumberOfChecks() == 0) { 466 if (original_ic_data.NumberOfChecks() == 0) {
480 // IC call for reoptimization populates original ICData. 467 // IC call for reoptimization populates original ICData.
481 equality_ic_data = original_ic_data.raw(); 468 equality_ic_data = original_ic_data.raw();
482 } else { 469 } else {
483 // Megamorphic call. 470 // Megamorphic call.
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 BranchInstr* branch, 646 BranchInstr* branch,
660 intptr_t deopt_id) { 647 intptr_t deopt_id) {
661 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 648 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
662 Register left = locs.in(0).reg(); 649 Register left = locs.in(0).reg();
663 Register right = locs.in(1).reg(); 650 Register right = locs.in(1).reg();
664 Register temp = locs.temp(0).reg(); 651 Register temp = locs.temp(0).reg();
665 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); 652 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality);
666 __ testq(left, Immediate(kSmiTagMask)); 653 __ testq(left, Immediate(kSmiTagMask));
667 __ j(ZERO, deopt); 654 __ j(ZERO, deopt);
668 // 'left' is not Smi. 655 // 'left' is not Smi.
669 const Immediate& raw_null = 656
670 Immediate(reinterpret_cast<intptr_t>(Object::null()));
671 Label identity_compare; 657 Label identity_compare;
672 __ cmpq(right, raw_null); 658 __ CompareObject(right, Object::Handle());
673 __ j(EQUAL, &identity_compare); 659 __ j(EQUAL, &identity_compare);
674 __ cmpq(left, raw_null); 660 __ CompareObject(left, Object::Handle());
675 __ j(EQUAL, &identity_compare); 661 __ j(EQUAL, &identity_compare);
676 662
677 __ LoadClassId(temp, left); 663 __ LoadClassId(temp, left);
678 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 664 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
679 const intptr_t len = ic_data.NumberOfChecks(); 665 const intptr_t len = ic_data.NumberOfChecks();
680 for (intptr_t i = 0; i < len; i++) { 666 for (intptr_t i = 0; i < len; i++) {
681 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); 667 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
682 if (i == (len - 1)) { 668 if (i == (len - 1)) {
683 __ j(NOT_EQUAL, deopt); 669 __ j(NOT_EQUAL, deopt);
684 } else { 670 } else {
(...skipping 26 matching lines...) Expand all
711 LocationSummary* locs, 697 LocationSummary* locs,
712 Token::Kind kind, 698 Token::Kind kind,
713 BranchInstr* branch, 699 BranchInstr* branch,
714 const ICData& ic_data, 700 const ICData& ic_data,
715 intptr_t deopt_id, 701 intptr_t deopt_id,
716 intptr_t token_pos) { 702 intptr_t token_pos) {
717 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 703 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
718 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 704 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
719 Register left = locs->in(0).reg(); 705 Register left = locs->in(0).reg();
720 Register right = locs->in(1).reg(); 706 Register right = locs->in(1).reg();
721 const Immediate& raw_null = 707
722 Immediate(reinterpret_cast<intptr_t>(Object::null()));
723 Label done, identity_compare, non_null_compare; 708 Label done, identity_compare, non_null_compare;
724 __ cmpq(right, raw_null); 709 __ CompareObject(right, Object::Handle());
725 __ j(EQUAL, &identity_compare, Assembler::kNearJump); 710 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
726 __ cmpq(left, raw_null); 711 __ CompareObject(left, Object::Handle());
727 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); 712 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
728 // Comparison with NULL is "===". 713 // Comparison with NULL is "===".
729 __ Bind(&identity_compare); 714 __ Bind(&identity_compare);
730 __ cmpq(left, right); 715 __ cmpq(left, right);
731 Condition cond = TokenKindToSmiCondition(kind); 716 Condition cond = TokenKindToSmiCondition(kind);
732 if (branch != NULL) { 717 if (branch != NULL) {
733 branch->EmitBranchOnCondition(compiler, cond); 718 branch->EmitBranchOnCondition(compiler, cond);
734 } else { 719 } else {
735 Register result = locs->out().reg(); 720 Register result = locs->out().reg();
736 Label load_true; 721 Label load_true;
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1687 } else if (RawObject::IsTypedDataClassId(field_cid)) {
1703 // Destroy value_cid_reg (safe because we are finished with it). 1688 // Destroy value_cid_reg (safe because we are finished with it).
1704 __ movq(value_cid_reg, 1689 __ movq(value_cid_reg,
1705 FieldAddress(value_reg, TypedData::length_offset())); 1690 FieldAddress(value_reg, TypedData::length_offset()));
1706 } 1691 }
1707 __ cmpq(value_cid_reg, field_length_operand); 1692 __ cmpq(value_cid_reg, field_length_operand);
1708 } 1693 }
1709 1694
1710 if (field().is_nullable() && (field_cid != kNullCid)) { 1695 if (field().is_nullable() && (field_cid != kNullCid)) {
1711 __ j(EQUAL, &ok); 1696 __ j(EQUAL, &ok);
1712 const Immediate& raw_null = 1697 __ CompareObject(value_reg, Object::Handle());
1713 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1714 __ cmpq(value_reg, raw_null);
1715 } 1698 }
1716 1699
1717 if (ok_is_fall_through) { 1700 if (ok_is_fall_through) {
1718 __ j(NOT_EQUAL, fail); 1701 __ j(NOT_EQUAL, fail);
1719 } else { 1702 } else {
1720 __ j(EQUAL, &ok); 1703 __ j(EQUAL, &ok);
1721 } 1704 }
1722 } else { 1705 } else {
1723 // Both value's and field's class id is known. 1706 // Both value's and field's class id is known.
1724 if ((value_cid != field_cid) && (value_cid != nullability)) { 1707 if ((value_cid != field_cid) && (value_cid != nullability)) {
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 // (or null). 1966 // (or null).
1984 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 1967 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
1985 !type_arguments().CanShareInstantiatorTypeArguments( 1968 !type_arguments().CanShareInstantiatorTypeArguments(
1986 instantiator_class())); 1969 instantiator_class()));
1987 // If the instantiator is null and if the type argument vector 1970 // If the instantiator is null and if the type argument vector
1988 // instantiated from null becomes a vector of dynamic, then use null as 1971 // instantiated from null becomes a vector of dynamic, then use null as
1989 // the type arguments. 1972 // the type arguments.
1990 Label type_arguments_instantiated; 1973 Label type_arguments_instantiated;
1991 const intptr_t len = type_arguments().Length(); 1974 const intptr_t len = type_arguments().Length();
1992 if (type_arguments().IsRawInstantiatedRaw(len)) { 1975 if (type_arguments().IsRawInstantiatedRaw(len)) {
1993 const Immediate& raw_null = 1976 __ CompareObject(instantiator_reg, Object::Handle());
1994 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1995 __ cmpq(instantiator_reg, raw_null);
1996 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1977 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1997 } 1978 }
1998 // Instantiate non-null type arguments. 1979 // Instantiate non-null type arguments.
1999 // A runtime call to instantiate the type arguments is required. 1980 // A runtime call to instantiate the type arguments is required.
2000 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1981 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2001 __ PushObject(type_arguments()); 1982 __ PushObject(type_arguments());
2002 __ pushq(instantiator_reg); // Push instantiator type arguments. 1983 __ pushq(instantiator_reg); // Push instantiator type arguments.
2003 compiler->GenerateCallRuntime(token_pos(), 1984 compiler->GenerateCallRuntime(token_pos(),
2004 deopt_id(), 1985 deopt_id(),
2005 kInstantiateTypeArgumentsRuntimeEntry, 1986 kInstantiateTypeArgumentsRuntimeEntry,
(...skipping 27 matching lines...) Expand all
2033 // instantiator_reg is the instantiator type argument vector, i.e. an 2014 // instantiator_reg is the instantiator type argument vector, i.e. an
2034 // AbstractTypeArguments object (or null). 2015 // AbstractTypeArguments object (or null).
2035 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2016 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2036 !type_arguments().CanShareInstantiatorTypeArguments( 2017 !type_arguments().CanShareInstantiatorTypeArguments(
2037 instantiator_class())); 2018 instantiator_class()));
2038 // If the instantiator is null and if the type argument vector 2019 // If the instantiator is null and if the type argument vector
2039 // instantiated from null becomes a vector of dynamic, then use null as 2020 // instantiated from null becomes a vector of dynamic, then use null as
2040 // the type arguments. 2021 // the type arguments.
2041 Label type_arguments_instantiated; 2022 Label type_arguments_instantiated;
2042 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 2023 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
2043 const Immediate& raw_null = 2024
2044 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2025 __ CompareObject(instantiator_reg, Object::Handle());
2045 __ cmpq(instantiator_reg, raw_null);
2046 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2026 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2047 // Instantiate non-null type arguments. 2027 // Instantiate non-null type arguments.
2048 // In the non-factory case, we rely on the allocation stub to 2028 // In the non-factory case, we rely on the allocation stub to
2049 // instantiate the type arguments. 2029 // instantiate the type arguments.
2050 __ LoadObject(result_reg, type_arguments()); 2030 __ LoadObject(result_reg, type_arguments());
2051 // result_reg: uninstantiated type arguments. 2031 // result_reg: uninstantiated type arguments.
2052 2032
2053 __ Bind(&type_arguments_instantiated); 2033 __ Bind(&type_arguments_instantiated);
2054 // result_reg: uninstantiated or instantiated type arguments. 2034 // result_reg: uninstantiated or instantiated type arguments.
2055 } 2035 }
(...skipping 19 matching lines...) Expand all
2075 // instantiator_reg is the instantiator AbstractTypeArguments object 2055 // instantiator_reg is the instantiator AbstractTypeArguments object
2076 // (or null). 2056 // (or null).
2077 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2057 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2078 !type_arguments().CanShareInstantiatorTypeArguments( 2058 !type_arguments().CanShareInstantiatorTypeArguments(
2079 instantiator_class())); 2059 instantiator_class()));
2080 2060
2081 // If the instantiator is null and if the type argument vector 2061 // If the instantiator is null and if the type argument vector
2082 // instantiated from null becomes a vector of dynamic, then use null as 2062 // instantiated from null becomes a vector of dynamic, then use null as
2083 // the type arguments and do not pass the instantiator. 2063 // the type arguments and do not pass the instantiator.
2084 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 2064 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
2085 const Immediate& raw_null = 2065
2086 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2087 Label instantiator_not_null; 2066 Label instantiator_not_null;
2088 __ cmpq(instantiator_reg, raw_null); 2067 __ CompareObject(instantiator_reg, Object::Handle());
2089 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); 2068 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
2090 // Null was used in VisitExtractConstructorTypeArguments as the 2069 // Null was used in VisitExtractConstructorTypeArguments as the
2091 // instantiated type arguments, no proper instantiator needed. 2070 // instantiated type arguments, no proper instantiator needed.
2092 __ movq(instantiator_reg, 2071 __ movq(instantiator_reg,
2093 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 2072 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2094 __ Bind(&instantiator_not_null); 2073 __ Bind(&instantiator_not_null);
2095 // instantiator_reg: instantiator or kNoInstantiator. 2074 // instantiator_reg: instantiator or kNoInstantiator.
2096 } 2075 }
2097 2076
2098 2077
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2154 } 2133 }
2155 2134
2156 2135
2157 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2136 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2158 __ Bind(compiler->GetJumpLabel(this)); 2137 __ Bind(compiler->GetJumpLabel(this));
2159 compiler->AddExceptionHandler(catch_try_index(), 2138 compiler->AddExceptionHandler(catch_try_index(),
2160 try_index(), 2139 try_index(),
2161 compiler->assembler()->CodeSize(), 2140 compiler->assembler()->CodeSize(),
2162 catch_handler_types_, 2141 catch_handler_types_,
2163 needs_stacktrace()); 2142 needs_stacktrace());
2143
2144 // Restore the pool pointer.
2145 __ LoadPoolPointer(PP);
2146
2164 if (HasParallelMove()) { 2147 if (HasParallelMove()) {
2165 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 2148 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
2166 } 2149 }
2167 2150
2168 // Restore RSP from RBP as we are coming from a throw and the code for 2151 // Restore RSP from RBP as we are coming from a throw and the code for
2169 // popping arguments has not been run. 2152 // popping arguments has not been run.
2170 const intptr_t fp_sp_dist = 2153 const intptr_t fp_sp_dist =
2171 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; 2154 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
2172 ASSERT(fp_sp_dist <= 0); 2155 ASSERT(fp_sp_dist <= 0);
2173 __ leaq(RSP, Address(RBP, fp_sp_dist)); 2156 __ leaq(RSP, Address(RBP, fp_sp_dist));
(...skipping 2124 matching lines...) Expand 10 before | Expand all | Expand 10 after
4298 summary->AddTemp(Location::RequiresRegister()); 4281 summary->AddTemp(Location::RequiresRegister());
4299 } 4282 }
4300 return summary; 4283 return summary;
4301 } 4284 }
4302 4285
4303 4286
4304 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4287 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4305 if (IsNullCheck()) { 4288 if (IsNullCheck()) {
4306 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4289 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4307 kDeoptCheckClass); 4290 kDeoptCheckClass);
4308 const Immediate& raw_null = 4291 __ CompareObject(locs()->in(0).reg(),
4309 Immediate(reinterpret_cast<intptr_t>(Object::null())); 4292 Object::Handle());
4310 __ cmpq(locs()->in(0).reg(), raw_null);
4311 __ j(EQUAL, deopt); 4293 __ j(EQUAL, deopt);
4312 return; 4294 return;
4313 } 4295 }
4314 4296
4315 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || 4297 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
4316 (unary_checks().NumberOfChecks() > 1)); 4298 (unary_checks().NumberOfChecks() > 1));
4317 Register value = locs()->in(0).reg(); 4299 Register value = locs()->in(0).reg();
4318 Register temp = locs()->temp(0).reg(); 4300 Register temp = locs()->temp(0).reg();
4319 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4301 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4320 kDeoptCheckClass); 4302 kDeoptCheckClass);
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
4806 PcDescriptors::kOther, 4788 PcDescriptors::kOther,
4807 locs()); 4789 locs());
4808 __ Drop(2); // Discard type arguments and receiver. 4790 __ Drop(2); // Discard type arguments and receiver.
4809 } 4791 }
4810 4792
4811 } // namespace dart 4793 } // namespace dart
4812 4794
4813 #undef __ 4795 #undef __
4814 4796
4815 #endif // defined TARGET_ARCH_X64 4797 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698