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

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

Issue 12049039: Fix source position for stack traces with optimized top function. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: avoid default arguments by using pending_deoptimization_env_ Created 7 years, 10 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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 LocationSummary* locs = 185 LocationSummary* locs =
186 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 186 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
187 locs->set_in(0, Location::RegisterLocation(RAX)); 187 locs->set_in(0, Location::RegisterLocation(RAX));
188 locs->set_out(Location::RegisterLocation(RAX)); 188 locs->set_out(Location::RegisterLocation(RAX));
189 return locs; 189 return locs;
190 } 190 }
191 191
192 192
193 static void EmitAssertBoolean(Register reg, 193 static void EmitAssertBoolean(Register reg,
194 intptr_t token_pos, 194 intptr_t token_pos,
195 intptr_t deopt_id,
195 LocationSummary* locs, 196 LocationSummary* locs,
196 FlowGraphCompiler* compiler) { 197 FlowGraphCompiler* compiler) {
197 // Check that the type of the value is allowed in conditional context. 198 // Check that the type of the value is allowed in conditional context.
198 // Call the runtime if the object is not bool::true or bool::false. 199 // Call the runtime if the object is not bool::true or bool::false.
199 ASSERT(locs->always_calls()); 200 ASSERT(locs->always_calls());
200 Label done; 201 Label done;
201 __ CompareObject(reg, Bool::True()); 202 __ CompareObject(reg, Bool::True());
202 __ j(EQUAL, &done, Assembler::kNearJump); 203 __ j(EQUAL, &done, Assembler::kNearJump);
203 __ CompareObject(reg, Bool::False()); 204 __ CompareObject(reg, Bool::False());
204 __ j(EQUAL, &done, Assembler::kNearJump); 205 __ j(EQUAL, &done, Assembler::kNearJump);
205 206
206 __ pushq(reg); // Push the source object. 207 __ pushq(reg); // Push the source object.
207 compiler->GenerateCallRuntime(token_pos, 208 compiler->GenerateCallRuntime(token_pos,
209 deopt_id,
208 kConditionTypeErrorRuntimeEntry, 210 kConditionTypeErrorRuntimeEntry,
209 locs); 211 locs);
210 // We should never return here. 212 // We should never return here.
211 __ int3(); 213 __ int3();
212 __ Bind(&done); 214 __ Bind(&done);
213 } 215 }
214 216
215 217
216 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 218 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
217 Register obj = locs()->in(0).reg(); 219 Register obj = locs()->in(0).reg();
218 Register result = locs()->out().reg(); 220 Register result = locs()->out().reg();
219 221
220 if (!is_eliminated()) { 222 if (!is_eliminated()) {
221 EmitAssertBoolean(obj, token_pos(), locs(), compiler); 223 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
222 } 224 }
223 ASSERT(obj == result); 225 ASSERT(obj == result);
224 } 226 }
225 227
226 228
227 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { 229 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const {
228 const intptr_t kNumInputs = 1; 230 const intptr_t kNumInputs = 1;
229 const intptr_t kNumTemps = 0; 231 const intptr_t kNumTemps = 0;
230 LocationSummary* locs = 232 LocationSummary* locs =
231 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 233 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
232 locs->set_in(0, Location::RegisterLocation(RAX)); 234 locs->set_in(0, Location::RegisterLocation(RAX));
233 locs->set_out(Location::RegisterLocation(RAX)); 235 locs->set_out(Location::RegisterLocation(RAX));
234 return locs; 236 return locs;
235 } 237 }
236 238
237 239
238 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 240 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
239 Register saved_args_desc = locs()->in(0).reg(); 241 Register saved_args_desc = locs()->in(0).reg();
240 Register result = locs()->out().reg(); 242 Register result = locs()->out().reg();
241 243
242 // Push the result place holder initialized to NULL. 244 // Push the result place holder initialized to NULL.
243 __ PushObject(Object::ZoneHandle()); 245 __ PushObject(Object::ZoneHandle());
244 __ pushq(Immediate(Smi::RawValue(formal_parameter_index()))); 246 __ pushq(Immediate(Smi::RawValue(formal_parameter_index())));
245 __ PushObject(formal_parameter_name()); 247 __ PushObject(formal_parameter_name());
246 __ pushq(saved_args_desc); 248 __ pushq(saved_args_desc);
247 compiler->GenerateCallRuntime(token_pos(), 249 compiler->GenerateCallRuntime(token_pos(),
250 deopt_id(),
248 kArgumentDefinitionTestRuntimeEntry, 251 kArgumentDefinitionTestRuntimeEntry,
249 locs()); 252 locs());
250 __ Drop(3); 253 __ Drop(3);
251 __ popq(result); // Pop bool result. 254 __ popq(result); // Pop bool result.
252 } 255 }
253 256
254 257
255 static Condition TokenKindToSmiCondition(Token::Kind kind) { 258 static Condition TokenKindToSmiCondition(Token::Kind kind) {
256 switch (kind) { 259 switch (kind) {
257 case Token::kEQ: return EQUAL; 260 case Token::kEQ: return EQUAL;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 __ CompareObject(RAX, Bool::True()); 492 __ CompareObject(RAX, Bool::True());
490 __ j(EQUAL, &false_label, Assembler::kNearJump); 493 __ j(EQUAL, &false_label, Assembler::kNearJump);
491 __ LoadObject(RAX, Bool::True()); 494 __ LoadObject(RAX, Bool::True());
492 __ jmp(&done); 495 __ jmp(&done);
493 __ Bind(&false_label); 496 __ Bind(&false_label);
494 __ LoadObject(RAX, Bool::False()); 497 __ LoadObject(RAX, Bool::False());
495 __ jmp(&done); 498 __ jmp(&done);
496 } 499 }
497 } else { 500 } else {
498 if (branch->is_checked()) { 501 if (branch->is_checked()) {
499 EmitAssertBoolean(RAX, token_pos, locs, compiler); 502 EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler);
500 } 503 }
501 __ CompareObject(RAX, Bool::True()); 504 __ CompareObject(RAX, Bool::True());
502 branch->EmitBranchOnCondition(compiler, cond); 505 branch->EmitBranchOnCondition(compiler, cond);
503 } 506 }
504 } 507 }
505 __ jmp(&done); 508 __ jmp(&done);
506 __ Bind(&next_test); 509 __ Bind(&next_test);
507 } 510 }
508 // Fall through leads to deoptimization 511 // Fall through leads to deoptimization
509 __ jmp(deopt); 512 __ jmp(deopt);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 Register right = locs()->in(1).reg(); 747 Register right = locs()->in(1).reg();
745 __ pushq(left); 748 __ pushq(left);
746 __ pushq(right); 749 __ pushq(right);
747 EmitEqualityAsInstanceCall(compiler, 750 EmitEqualityAsInstanceCall(compiler,
748 deopt_id(), 751 deopt_id(),
749 token_pos(), 752 token_pos(),
750 Token::kEQ, // kNE reverse occurs at branch. 753 Token::kEQ, // kNE reverse occurs at branch.
751 locs(), 754 locs(),
752 *ic_data()); 755 *ic_data());
753 if (branch->is_checked()) { 756 if (branch->is_checked()) {
754 EmitAssertBoolean(RAX, token_pos(), locs(), compiler); 757 EmitAssertBoolean(RAX, token_pos(), deopt_id(), locs(), compiler);
755 } 758 }
756 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 759 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
757 __ CompareObject(RAX, Bool::True()); 760 __ CompareObject(RAX, Bool::True());
758 branch->EmitBranchOnCondition(compiler, branch_condition); 761 branch->EmitBranchOnCondition(compiler, branch_condition);
759 } 762 }
760 763
761 764
762 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 765 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
763 const intptr_t kNumInputs = 2; 766 const intptr_t kNumInputs = 2;
764 const intptr_t kNumTemps = 0; 767 const intptr_t kNumTemps = 0;
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 return summary; 1378 return summary;
1376 } 1379 }
1377 1380
1378 1381
1379 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1382 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1380 ASSERT(locs()->in(0).reg() == RAX); // Value. 1383 ASSERT(locs()->in(0).reg() == RAX); // Value.
1381 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 1384 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
1382 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 1385 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
1383 1386
1384 compiler->GenerateInstanceOf(token_pos(), 1387 compiler->GenerateInstanceOf(token_pos(),
1388 deopt_id(),
1385 type(), 1389 type(),
1386 negate_result(), 1390 negate_result(),
1387 locs()); 1391 locs());
1388 ASSERT(locs()->out().reg() == RAX); 1392 ASSERT(locs()->out().reg() == RAX);
1389 } 1393 }
1390 1394
1391 1395
1392 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { 1396 LocationSummary* CreateArrayInstr::MakeLocationSummary() const {
1393 const intptr_t kNumInputs = 1; 1397 const intptr_t kNumInputs = 1;
1394 const intptr_t kNumTemps = 0; 1398 const intptr_t kNumTemps = 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 Register type_arguments = locs()->in(0).reg(); 1441 Register type_arguments = locs()->in(0).reg();
1438 Register instantiator_type_arguments = locs()->in(1).reg(); 1442 Register instantiator_type_arguments = locs()->in(1).reg();
1439 Register result = locs()->out().reg(); 1443 Register result = locs()->out().reg();
1440 1444
1441 // Push the result place holder initialized to NULL. 1445 // Push the result place holder initialized to NULL.
1442 __ PushObject(Object::ZoneHandle()); 1446 __ PushObject(Object::ZoneHandle());
1443 __ PushObject(cls); 1447 __ PushObject(cls);
1444 __ pushq(type_arguments); 1448 __ pushq(type_arguments);
1445 __ pushq(instantiator_type_arguments); 1449 __ pushq(instantiator_type_arguments);
1446 compiler->GenerateCallRuntime(token_pos(), 1450 compiler->GenerateCallRuntime(token_pos(),
1451 deopt_id(),
1447 kAllocateObjectWithBoundsCheckRuntimeEntry, 1452 kAllocateObjectWithBoundsCheckRuntimeEntry,
1448 locs()); 1453 locs());
1449 // Pop instantiator type arguments, type arguments, and class. 1454 // Pop instantiator type arguments, type arguments, and class.
1450 __ Drop(3); 1455 __ Drop(3);
1451 __ popq(result); // Pop new instance. 1456 __ popq(result); // Pop new instance.
1452 } 1457 }
1453 1458
1454 1459
1455 LocationSummary* LoadFieldInstr::MakeLocationSummary() const { 1460 LocationSummary* LoadFieldInstr::MakeLocationSummary() const {
1456 return LocationSummary::Make(1, 1461 return LocationSummary::Make(1,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1514 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1510 Immediate(Smi::RawValue(len))); 1515 Immediate(Smi::RawValue(len)));
1511 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1516 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1512 __ Bind(&type_arguments_uninstantiated); 1517 __ Bind(&type_arguments_uninstantiated);
1513 } 1518 }
1514 // A runtime call to instantiate the type arguments is required. 1519 // A runtime call to instantiate the type arguments is required.
1515 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1520 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1516 __ PushObject(type_arguments()); 1521 __ PushObject(type_arguments());
1517 __ pushq(instantiator_reg); // Push instantiator type arguments. 1522 __ pushq(instantiator_reg); // Push instantiator type arguments.
1518 compiler->GenerateCallRuntime(token_pos(), 1523 compiler->GenerateCallRuntime(token_pos(),
1524 deopt_id(),
1519 kInstantiateTypeArgumentsRuntimeEntry, 1525 kInstantiateTypeArgumentsRuntimeEntry,
1520 locs()); 1526 locs());
1521 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1527 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1522 __ popq(result_reg); // Pop instantiated type arguments. 1528 __ popq(result_reg); // Pop instantiated type arguments.
1523 __ Bind(&type_arguments_instantiated); 1529 __ Bind(&type_arguments_instantiated);
1524 ASSERT(instantiator_reg == result_reg); 1530 ASSERT(instantiator_reg == result_reg);
1525 // 'result_reg': Instantiated type arguments. 1531 // 'result_reg': Instantiated type arguments.
1526 } 1532 }
1527 1533
1528 1534
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 } 1689 }
1684 1690
1685 1691
1686 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1692 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1687 Register context_value = locs()->in(0).reg(); 1693 Register context_value = locs()->in(0).reg();
1688 Register result = locs()->out().reg(); 1694 Register result = locs()->out().reg();
1689 1695
1690 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1696 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1691 __ pushq(context_value); 1697 __ pushq(context_value);
1692 compiler->GenerateCallRuntime(token_pos(), 1698 compiler->GenerateCallRuntime(token_pos(),
1699 deopt_id(),
1693 kCloneContextRuntimeEntry, 1700 kCloneContextRuntimeEntry,
1694 locs()); 1701 locs());
1695 __ popq(result); // Remove argument. 1702 __ popq(result); // Remove argument.
1696 __ popq(result); // Get result (cloned context). 1703 __ popq(result); // Get result (cloned context).
1697 } 1704 }
1698 1705
1699 1706
1700 LocationSummary* CatchEntryInstr::MakeLocationSummary() const { 1707 LocationSummary* CatchEntryInstr::MakeLocationSummary() const {
1701 return LocationSummary::Make(0, 1708 return LocationSummary::Make(0,
1702 Location::NoLocation(), 1709 Location::NoLocation(),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 1745
1739 class CheckStackOverflowSlowPath : public SlowPathCode { 1746 class CheckStackOverflowSlowPath : public SlowPathCode {
1740 public: 1747 public:
1741 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) 1748 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction)
1742 : instruction_(instruction) { } 1749 : instruction_(instruction) { }
1743 1750
1744 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1751 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1745 __ Comment("CheckStackOverflowSlowPath"); 1752 __ Comment("CheckStackOverflowSlowPath");
1746 __ Bind(entry_label()); 1753 __ Bind(entry_label());
1747 compiler->SaveLiveRegisters(instruction_->locs()); 1754 compiler->SaveLiveRegisters(instruction_->locs());
1755 // pending_deoptimization_env_ is needed to generate a runtime call that
1756 // may throw an exception.
1757 ASSERT(compiler->pending_deoptimization_env_ == NULL);
1758 compiler->pending_deoptimization_env_ = instruction_->env();
1748 compiler->GenerateCallRuntime(instruction_->token_pos(), 1759 compiler->GenerateCallRuntime(instruction_->token_pos(),
1760 instruction_->deopt_id(),
1749 kStackOverflowRuntimeEntry, 1761 kStackOverflowRuntimeEntry,
1750 instruction_->locs()); 1762 instruction_->locs());
1763 compiler->pending_deoptimization_env_ = NULL;
1751 compiler->RestoreLiveRegisters(instruction_->locs()); 1764 compiler->RestoreLiveRegisters(instruction_->locs());
1752 __ jmp(exit_label()); 1765 __ jmp(exit_label());
1753 } 1766 }
1754 1767
1755 private: 1768 private:
1756 CheckStackOverflowInstr* instruction_; 1769 CheckStackOverflowInstr* instruction_;
1757 }; 1770 };
1758 1771
1759 1772
1760 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1773 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 } 2684 }
2672 2685
2673 2686
2674 LocationSummary* ThrowInstr::MakeLocationSummary() const { 2687 LocationSummary* ThrowInstr::MakeLocationSummary() const {
2675 return new LocationSummary(0, 0, LocationSummary::kCall); 2688 return new LocationSummary(0, 0, LocationSummary::kCall);
2676 } 2689 }
2677 2690
2678 2691
2679 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2692 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2680 compiler->GenerateCallRuntime(token_pos(), 2693 compiler->GenerateCallRuntime(token_pos(),
2694 deopt_id(),
2681 kThrowRuntimeEntry, 2695 kThrowRuntimeEntry,
2682 locs()); 2696 locs());
2683 __ int3(); 2697 __ int3();
2684 } 2698 }
2685 2699
2686 2700
2687 LocationSummary* ReThrowInstr::MakeLocationSummary() const { 2701 LocationSummary* ReThrowInstr::MakeLocationSummary() const {
2688 return new LocationSummary(0, 0, LocationSummary::kCall); 2702 return new LocationSummary(0, 0, LocationSummary::kCall);
2689 } 2703 }
2690 2704
2691 2705
2692 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2706 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2693 compiler->GenerateCallRuntime(token_pos(), 2707 compiler->GenerateCallRuntime(token_pos(),
2708 deopt_id(),
2694 kReThrowRuntimeEntry, 2709 kReThrowRuntimeEntry,
2695 locs()); 2710 locs());
2696 __ int3(); 2711 __ int3();
2697 } 2712 }
2698 2713
2699 2714
2700 LocationSummary* GotoInstr::MakeLocationSummary() const { 2715 LocationSummary* GotoInstr::MakeLocationSummary() const {
2701 return new LocationSummary(0, 0, LocationSummary::kNoCall); 2716 return new LocationSummary(0, 0, LocationSummary::kNoCall);
2702 } 2717 }
2703 2718
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 PcDescriptors::kOther, 2994 PcDescriptors::kOther,
2980 locs()); 2995 locs());
2981 __ Drop(2); // Discard type arguments and receiver. 2996 __ Drop(2); // Discard type arguments and receiver.
2982 } 2997 }
2983 2998
2984 } // namespace dart 2999 } // namespace dart
2985 3000
2986 #undef __ 3001 #undef __
2987 3002
2988 #endif // defined TARGET_ARCH_X64 3003 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698