OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/error.h" | 8 #include "lib/error.h" |
9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
12 #include "vm/parser.h" | 12 #include "vm/parser.h" |
13 #include "vm/stub_code.h" | 13 #include "vm/stub_code.h" |
14 | 14 |
15 #define __ compiler->assembler()-> | 15 #define __ compiler->assembler()-> |
16 | 16 |
17 namespace dart { | 17 namespace dart { |
18 | 18 |
| 19 DECLARE_FLAG(bool, optimization_counter_threshold); |
| 20 DECLARE_FLAG(bool, trace_functions); |
19 | 21 |
20 // True iff. the arguments to a call will be properly pushed and can | 22 // True iff. the arguments to a call will be properly pushed and can |
21 // be popped after the call. | 23 // be popped after the call. |
22 template <typename T> static bool VerifyCallComputation(T* comp) { | 24 template <typename T> static bool VerifyCallComputation(T* comp) { |
23 // Argument values should be consecutive temps. | 25 // Argument values should be consecutive temps. |
24 // | 26 // |
25 // TODO(kmillikin): implement stack height tracking so we can also assert | 27 // TODO(kmillikin): implement stack height tracking so we can also assert |
26 // they are on top of the stack. | 28 // they are on top of the stack. |
27 intptr_t previous = -1; | 29 intptr_t previous = -1; |
28 for (int i = 0; i < comp->ArgumentCount(); ++i) { | 30 for (int i = 0; i < comp->ArgumentCount(); ++i) { |
(...skipping 16 matching lines...) Expand all Loading... |
45 v2->AsUse()->definition()->temp_index(); | 47 v2->AsUse()->definition()->temp_index(); |
46 } | 48 } |
47 | 49 |
48 | 50 |
49 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 51 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
50 computation()->EmitNativeCode(compiler); | 52 computation()->EmitNativeCode(compiler); |
51 __ pushq(locs()->out().reg()); | 53 __ pushq(locs()->out().reg()); |
52 } | 54 } |
53 | 55 |
54 | 56 |
55 static LocationSummary* MakeSimpleLocationSummary( | 57 LocationSummary* ReturnInstr::locs() { |
56 intptr_t input_count, Location out) { | 58 if (locs_ == NULL) { |
57 LocationSummary* summary = new LocationSummary(input_count, 0); | 59 const intptr_t kNumInputs = 1; |
58 for (intptr_t i = 0; i < input_count; i++) { | 60 const intptr_t kNumTemps = 1; |
59 summary->set_in(i, Location::RequiresRegister()); | 61 locs_ = new LocationSummary(kNumInputs, kNumTemps); |
| 62 locs_->set_in(0, Location::RegisterLocation(RAX)); |
| 63 locs_->set_temp(0, Location::RequiresRegister()); |
60 } | 64 } |
61 summary->set_out(out); | 65 return locs_; |
62 return summary; | 66 } |
| 67 |
| 68 |
| 69 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 70 Register result = locs()->in(0).reg(); |
| 71 Register temp = locs()->temp(0).reg(); |
| 72 ASSERT(result == RAX); |
| 73 if (!compiler->is_optimizing()) { |
| 74 // Count only in unoptimized code. |
| 75 // TODO(srdjan): Replace the counting code with a type feedback |
| 76 // collection and counting stub. |
| 77 const Function& function = |
| 78 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| 79 __ LoadObject(temp, function); |
| 80 __ incq(FieldAddress(temp, Function::usage_counter_offset())); |
| 81 if (CodeGenerator::CanOptimize()) { |
| 82 // Do not optimize if usage count must be reported. |
| 83 __ cmpl(FieldAddress(temp, Function::usage_counter_offset()), |
| 84 Immediate(FLAG_optimization_counter_threshold)); |
| 85 Label not_yet_hot; |
| 86 __ j(LESS_EQUAL, ¬_yet_hot, Assembler::kNearJump); |
| 87 __ pushq(result); // Preserve result. |
| 88 __ pushq(temp); // Argument for runtime: function to optimize. |
| 89 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
| 90 __ popq(temp); // Remove argument. |
| 91 __ popq(result); // Restore result. |
| 92 __ Bind(¬_yet_hot); |
| 93 } |
| 94 } |
| 95 if (FLAG_trace_functions) { |
| 96 __ pushq(result); // Preserve result. |
| 97 const Function& function = |
| 98 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| 99 __ LoadObject(temp, function); |
| 100 __ pushq(temp); |
| 101 compiler->GenerateCallRuntime(AstNode::kNoId, |
| 102 0, |
| 103 CatchClauseNode::kInvalidTryIndex, |
| 104 kTraceFunctionExitRuntimeEntry); |
| 105 __ popq(temp); // Remove argument. |
| 106 __ popq(result); // Restore result. |
| 107 } |
| 108 __ LeaveFrame(); |
| 109 __ ret(); |
| 110 |
| 111 // Generate 8 bytes of NOPs so that the debugger can patch the |
| 112 // return pattern with a call to the debug stub. |
| 113 __ nop(1); |
| 114 __ nop(1); |
| 115 __ nop(1); |
| 116 __ nop(1); |
| 117 __ nop(1); |
| 118 __ nop(1); |
| 119 __ nop(1); |
| 120 __ nop(1); |
| 121 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
| 122 cid(), |
| 123 token_index(), |
| 124 CatchClauseNode::kInvalidTryIndex); |
63 } | 125 } |
64 | 126 |
65 | 127 |
66 LocationSummary* CurrentContextComp::MakeLocationSummary() const { | 128 LocationSummary* CurrentContextComp::MakeLocationSummary() const { |
67 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 129 return LocationSummary::Make(0, Location::RequiresRegister()); |
68 } | 130 } |
69 | 131 |
70 | 132 |
71 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 133 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
72 __ movq(locs()->out().reg(), CTX); | 134 __ movq(locs()->out().reg(), CTX); |
73 } | 135 } |
74 | 136 |
75 | 137 |
76 LocationSummary* StoreContextComp::MakeLocationSummary() const { | 138 LocationSummary* StoreContextComp::MakeLocationSummary() const { |
77 LocationSummary* summary = new LocationSummary(1, 0); | 139 LocationSummary* summary = new LocationSummary(1, 0); |
78 summary->set_in(0, Location::RegisterLocation(CTX)); | 140 summary->set_in(0, Location::RegisterLocation(CTX)); |
79 return summary; | 141 return summary; |
80 } | 142 } |
81 | 143 |
82 | 144 |
83 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 145 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
84 // Nothing to do. Context register were loaded by register allocator. | 146 // Nothing to do. Context register were loaded by register allocator. |
85 ASSERT(locs()->in(0).reg() == CTX); | 147 ASSERT(locs()->in(0).reg() == CTX); |
86 } | 148 } |
87 | 149 |
88 | 150 |
89 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 151 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
90 return MakeSimpleLocationSummary(2, Location::SameAsFirstInput()); | 152 return LocationSummary::Make(2, Location::SameAsFirstInput()); |
91 } | 153 } |
92 | 154 |
93 | 155 |
94 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 156 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
95 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 157 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
96 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 158 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
97 | 159 |
98 Register left = locs()->in(0).reg(); | 160 Register left = locs()->in(0).reg(); |
99 Register right = locs()->in(1).reg(); | 161 Register right = locs()->in(1).reg(); |
100 Register result = locs()->out().reg(); | 162 Register result = locs()->out().reg(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 ASSERT(VerifyCallComputation(this)); | 239 ASSERT(VerifyCallComputation(this)); |
178 compiler->EmitStaticCall(token_index(), | 240 compiler->EmitStaticCall(token_index(), |
179 try_index(), | 241 try_index(), |
180 function(), | 242 function(), |
181 ArgumentCount(), | 243 ArgumentCount(), |
182 argument_names()); | 244 argument_names()); |
183 } | 245 } |
184 | 246 |
185 | 247 |
186 LocationSummary* LoadLocalComp::MakeLocationSummary() const { | 248 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
187 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 249 return LocationSummary::Make(0, Location::RequiresRegister()); |
188 } | 250 } |
189 | 251 |
190 | 252 |
191 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 253 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
192 Register result = locs()->out().reg(); | 254 Register result = locs()->out().reg(); |
193 __ movq(result, Address(RBP, local().index() * kWordSize)); | 255 __ movq(result, Address(RBP, local().index() * kWordSize)); |
194 } | 256 } |
195 | 257 |
196 | 258 |
197 LocationSummary* StoreLocalComp::MakeLocationSummary() const { | 259 LocationSummary* StoreLocalComp::MakeLocationSummary() const { |
198 return MakeSimpleLocationSummary(1, Location::SameAsFirstInput()); | 260 return LocationSummary::Make(1, Location::SameAsFirstInput()); |
199 } | 261 } |
200 | 262 |
201 | 263 |
202 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 264 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
203 Register value = locs()->in(0).reg(); | 265 Register value = locs()->in(0).reg(); |
204 Register result = locs()->out().reg(); | 266 Register result = locs()->out().reg(); |
205 ASSERT(result == value); // Assert that register assignment is correct. | 267 ASSERT(result == value); // Assert that register assignment is correct. |
206 __ movq(Address(RBP, local().index() * kWordSize), value); | 268 __ movq(Address(RBP, local().index() * kWordSize), value); |
207 } | 269 } |
208 | 270 |
209 | 271 |
210 LocationSummary* ConstantVal::MakeLocationSummary() const { | 272 LocationSummary* ConstantVal::MakeLocationSummary() const { |
211 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 273 return LocationSummary::Make(0, Location::RequiresRegister()); |
212 } | 274 } |
213 | 275 |
214 | 276 |
215 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { | 277 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { |
216 Register result = locs()->out().reg(); | 278 Register result = locs()->out().reg(); |
217 if (value().IsSmi()) { | 279 if (value().IsSmi()) { |
218 int64_t imm = reinterpret_cast<int64_t>(value().raw()); | 280 int64_t imm = reinterpret_cast<int64_t>(value().raw()); |
219 __ movq(result, Immediate(imm)); | 281 __ movq(result, Immediate(imm)); |
220 } else { | 282 } else { |
221 __ LoadObject(result, value()); | 283 __ LoadObject(result, value()); |
(...skipping 29 matching lines...) Expand all Loading... |
251 compiler->GenerateAssertAssignable(cid(), | 313 compiler->GenerateAssertAssignable(cid(), |
252 token_index(), | 314 token_index(), |
253 try_index(), | 315 try_index(), |
254 dst_type(), | 316 dst_type(), |
255 dst_name()); | 317 dst_name()); |
256 ASSERT(locs()->in(0).reg() == locs()->out().reg()); | 318 ASSERT(locs()->in(0).reg() == locs()->out().reg()); |
257 } | 319 } |
258 | 320 |
259 | 321 |
260 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { | 322 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
261 return MakeSimpleLocationSummary(1, Location::SameAsFirstInput()); | 323 return LocationSummary::Make(1, Location::SameAsFirstInput()); |
262 } | 324 } |
263 | 325 |
264 | 326 |
265 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 327 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
266 Register obj = locs()->in(0).reg(); | 328 Register obj = locs()->in(0).reg(); |
267 Register result = locs()->out().reg(); | 329 Register result = locs()->out().reg(); |
268 | 330 |
269 // Check that the type of the value is allowed in conditional context. | 331 // Check that the type of the value is allowed in conditional context. |
270 // Call the runtime if the object is not bool::true or bool::false. | 332 // Call the runtime if the object is not bool::true or bool::false. |
271 Label done; | 333 Label done; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 kNumArgumentsChecked); | 399 kNumArgumentsChecked); |
338 __ Bind(&done); | 400 __ Bind(&done); |
339 } | 401 } |
340 | 402 |
341 | 403 |
342 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 404 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
343 LocationSummary* locs = new LocationSummary(0, 3); | 405 LocationSummary* locs = new LocationSummary(0, 3); |
344 locs->set_temp(0, Location::RegisterLocation(RAX)); | 406 locs->set_temp(0, Location::RegisterLocation(RAX)); |
345 locs->set_temp(1, Location::RegisterLocation(RBX)); | 407 locs->set_temp(1, Location::RegisterLocation(RBX)); |
346 locs->set_temp(2, Location::RegisterLocation(R10)); | 408 locs->set_temp(2, Location::RegisterLocation(R10)); |
347 locs->set_out(Location::RegisterLocation(RAX)); | 409 locs->set_out(Location::RequiresRegister()); |
348 return locs; | 410 return locs; |
349 } | 411 } |
350 | 412 |
351 | 413 |
352 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 414 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
353 ASSERT(locs()->temp(0).reg() == RAX); | 415 ASSERT(locs()->temp(0).reg() == RAX); |
354 ASSERT(locs()->temp(1).reg() == RBX); | 416 ASSERT(locs()->temp(1).reg() == RBX); |
355 ASSERT(locs()->temp(2).reg() == R10); | 417 ASSERT(locs()->temp(2).reg() == R10); |
356 ASSERT(locs()->out().reg() == RAX); | 418 Register result = locs()->out().reg(); |
357 | 419 |
358 // Push the result place holder initialized to NULL. | 420 // Push the result place holder initialized to NULL. |
359 __ PushObject(Object::ZoneHandle()); | 421 __ PushObject(Object::ZoneHandle()); |
360 // Pass a pointer to the first argument in RAX. | 422 // Pass a pointer to the first argument in RAX. |
361 if (!has_optional_parameters()) { | 423 if (!has_optional_parameters()) { |
362 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); | 424 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); |
363 } else { | 425 } else { |
364 __ leaq(RAX, | 426 __ leaq(RAX, |
365 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 427 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
366 } | 428 } |
367 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 429 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
368 __ movq(R10, Immediate(argument_count())); | 430 __ movq(R10, Immediate(argument_count())); |
369 compiler->GenerateCall(token_index(), | 431 compiler->GenerateCall(token_index(), |
370 try_index(), | 432 try_index(), |
371 &StubCode::CallNativeCFunctionLabel(), | 433 &StubCode::CallNativeCFunctionLabel(), |
372 PcDescriptors::kOther); | 434 PcDescriptors::kOther); |
373 __ popq(RAX); | 435 __ popq(result); |
374 } | 436 } |
375 | 437 |
376 | 438 |
377 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 439 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
378 const intptr_t kNumInputs = 3; | 440 const intptr_t kNumInputs = 3; |
379 return MakeSimpleLocationSummary(kNumInputs, Location::NoLocation()); | 441 return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
380 } | 442 } |
381 | 443 |
382 | 444 |
383 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 445 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
384 Register receiver = locs()->in(0).reg(); | 446 Register receiver = locs()->in(0).reg(); |
385 Register index = locs()->in(1).reg(); | 447 Register index = locs()->in(1).reg(); |
386 Register value = locs()->in(2).reg(); | 448 Register value = locs()->in(2).reg(); |
387 | 449 |
388 const String& function_name = | 450 const String& function_name = |
389 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 451 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
390 | 452 |
391 __ pushq(receiver); | 453 __ pushq(receiver); |
392 __ pushq(index); | 454 __ pushq(index); |
393 __ pushq(value); | 455 __ pushq(value); |
394 const intptr_t kNumArguments = 3; | 456 const intptr_t kNumArguments = 3; |
395 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 457 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
396 compiler->EmitInstanceCall(cid(), | 458 compiler->EmitInstanceCall(cid(), |
397 token_index(), | 459 token_index(), |
398 try_index(), | 460 try_index(), |
399 function_name, | 461 function_name, |
400 kNumArguments, | 462 kNumArguments, |
401 Array::ZoneHandle(), // No optional arguments. | 463 Array::ZoneHandle(), // No optional arguments. |
402 kNumArgsChecked); | 464 kNumArgsChecked); |
403 } | 465 } |
404 | 466 |
405 | 467 |
406 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { | 468 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
407 const intptr_t kNumInputs = 2; | 469 const intptr_t kNumInputs = 2; |
408 return MakeSimpleLocationSummary(kNumInputs, Location::RequiresRegister()); | 470 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
409 return NULL; | 471 return NULL; |
410 } | 472 } |
411 | 473 |
412 | 474 |
413 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 475 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
414 Register receiver = locs()->in(0).reg(); | 476 Register receiver = locs()->in(0).reg(); |
415 Register value = locs()->in(1).reg(); | 477 Register value = locs()->in(1).reg(); |
416 Register result = locs()->out().reg(); | 478 Register result = locs()->out().reg(); |
417 | 479 |
418 // Preserve the value (second argument) under the arguments as the result | 480 // Preserve the value (second argument) under the arguments as the result |
(...skipping 12 matching lines...) Expand all Loading... |
431 function_name, | 493 function_name, |
432 2, | 494 2, |
433 Array::ZoneHandle(), | 495 Array::ZoneHandle(), |
434 1); | 496 1); |
435 __ popq(result); | 497 __ popq(result); |
436 } | 498 } |
437 | 499 |
438 | 500 |
439 LocationSummary* StaticSetterComp::MakeLocationSummary() const { | 501 LocationSummary* StaticSetterComp::MakeLocationSummary() const { |
440 const intptr_t kNumInputs = 1; | 502 const intptr_t kNumInputs = 1; |
441 return MakeSimpleLocationSummary(kNumInputs, Location::RequiresRegister()); | 503 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
442 } | 504 } |
443 | 505 |
444 | 506 |
445 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 507 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
446 Register value = locs()->in(0).reg(); | 508 Register value = locs()->in(0).reg(); |
447 Register result = locs()->out().reg(); | 509 Register result = locs()->out().reg(); |
448 | 510 |
449 // Preserve the argument as the result of the computation, | 511 // Preserve the argument as the result of the computation, |
450 // then call the setter. | 512 // then call the setter. |
451 | 513 |
452 // Duplicate the argument. | 514 // Duplicate the argument. |
453 // TODO(fschneider): Avoid preserving the value if the result is not used. | 515 // TODO(fschneider): Avoid preserving the value if the result is not used. |
454 __ pushq(value); | 516 __ pushq(value); |
455 __ pushq(value); | 517 __ pushq(value); |
456 compiler->EmitStaticCall(token_index(), | 518 compiler->EmitStaticCall(token_index(), |
457 try_index(), | 519 try_index(), |
458 setter_function(), | 520 setter_function(), |
459 1, | 521 1, |
460 Array::ZoneHandle()); | 522 Array::ZoneHandle()); |
461 __ popq(result); | 523 __ popq(result); |
462 } | 524 } |
463 | 525 |
464 | 526 |
465 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { | 527 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
466 // TODO(fschneider): For this instruction the input register may be | 528 // TODO(fschneider): For this instruction the input register may be |
467 // reused for the result (but is not required to) because the input | 529 // reused for the result (but is not required to) because the input |
468 // is not used after the result is defined. We should consider adding | 530 // is not used after the result is defined. We should consider adding |
469 // this information to the input policy. | 531 // this information to the input policy. |
470 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 532 return LocationSummary::Make(1, Location::RequiresRegister()); |
471 } | 533 } |
472 | 534 |
473 | 535 |
474 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 536 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
475 Register instance = locs()->in(0).reg(); | 537 Register instance = locs()->in(0).reg(); |
476 Register result = locs()->out().reg(); | 538 Register result = locs()->out().reg(); |
477 | 539 |
478 __ movq(result, FieldAddress(instance, field().Offset())); | 540 __ movq(result, FieldAddress(instance, field().Offset())); |
479 } | 541 } |
480 | 542 |
481 | 543 |
482 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { | 544 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
483 return MakeSimpleLocationSummary(2, Location::RequiresRegister()); | 545 return LocationSummary::Make(2, Location::RequiresRegister()); |
484 } | 546 } |
485 | 547 |
486 | 548 |
487 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 549 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
488 ASSERT(VerifyValues(instance(), value())); | 550 ASSERT(VerifyValues(instance(), value())); |
489 Register instance = locs()->in(0).reg(); | 551 Register instance = locs()->in(0).reg(); |
490 Register value = locs()->in(1).reg(); | 552 Register value = locs()->in(1).reg(); |
491 Register result = locs()->out().reg(); | 553 Register result = locs()->out().reg(); |
492 | 554 |
493 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()), | 555 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()), |
494 value); | 556 value); |
495 // TODO(fschneider): Consider eliminating this move by specifying a | 557 // TODO(fschneider): Consider eliminating this move by specifying a |
496 // SameAsSecondInput for the result. | 558 // SameAsSecondInput for the result. |
497 if (result != value) { | 559 if (result != value) { |
498 __ movq(result, value); | 560 __ movq(result, value); |
499 } | 561 } |
500 } | 562 } |
501 | 563 |
502 | 564 |
503 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { | 565 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
504 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 566 return LocationSummary::Make(0, Location::RequiresRegister()); |
505 } | 567 } |
506 | 568 |
507 | 569 |
508 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 570 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
509 Register result = locs()->out().reg(); | 571 Register result = locs()->out().reg(); |
510 __ LoadObject(result, field()); | 572 __ LoadObject(result, field()); |
511 __ movq(result, FieldAddress(result, Field::value_offset())); | 573 __ movq(result, FieldAddress(result, Field::value_offset())); |
512 } | 574 } |
513 | 575 |
514 | 576 |
(...skipping 10 matching lines...) Expand all Loading... |
525 Register value = locs()->in(0).reg(); | 587 Register value = locs()->in(0).reg(); |
526 Register temp = locs()->temp(0).reg(); | 588 Register temp = locs()->temp(0).reg(); |
527 ASSERT(locs()->out().reg() == value); | 589 ASSERT(locs()->out().reg() == value); |
528 | 590 |
529 __ LoadObject(temp, field()); | 591 __ LoadObject(temp, field()); |
530 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); | 592 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); |
531 } | 593 } |
532 | 594 |
533 | 595 |
534 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { | 596 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { |
535 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 597 return LocationSummary::Make(1, Location::RequiresRegister()); |
536 } | 598 } |
537 | 599 |
538 | 600 |
539 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 601 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
540 Register value = locs()->in(0).reg(); | 602 Register value = locs()->in(0).reg(); |
541 Register result = locs()->out().reg(); | 603 Register result = locs()->out().reg(); |
542 | 604 |
543 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 605 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
544 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 606 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
545 Label done; | 607 Label done; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 compiler->GenerateCall(token_index(), | 711 compiler->GenerateCall(token_index(), |
650 try_index(), | 712 try_index(), |
651 &label, | 713 &label, |
652 PcDescriptors::kOther); | 714 PcDescriptors::kOther); |
653 __ Drop(arguments().length()); // Discard arguments. | 715 __ Drop(arguments().length()); // Discard arguments. |
654 } | 716 } |
655 | 717 |
656 | 718 |
657 LocationSummary* AllocateObjectWithBoundsCheckComp:: | 719 LocationSummary* AllocateObjectWithBoundsCheckComp:: |
658 MakeLocationSummary() const { | 720 MakeLocationSummary() const { |
659 return MakeSimpleLocationSummary(2, Location::RequiresRegister()); | 721 return LocationSummary::Make(2, Location::RequiresRegister()); |
660 } | 722 } |
661 | 723 |
662 | 724 |
663 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 725 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
664 FlowGraphCompiler* compiler) { | 726 FlowGraphCompiler* compiler) { |
665 const Class& cls = Class::ZoneHandle(constructor().owner()); | 727 const Class& cls = Class::ZoneHandle(constructor().owner()); |
666 Register type_arguments = locs()->in(0).reg(); | 728 Register type_arguments = locs()->in(0).reg(); |
667 Register instantiator_type_arguments = locs()->in(1).reg(); | 729 Register instantiator_type_arguments = locs()->in(1).reg(); |
668 Register result = locs()->out().reg(); | 730 Register result = locs()->out().reg(); |
669 | 731 |
670 // Push the result place holder initialized to NULL. | 732 // Push the result place holder initialized to NULL. |
671 __ PushObject(Object::ZoneHandle()); | 733 __ PushObject(Object::ZoneHandle()); |
672 __ pushq(Immediate(Smi::RawValue(token_index()))); | 734 __ pushq(Immediate(Smi::RawValue(token_index()))); |
673 __ PushObject(cls); | 735 __ PushObject(cls); |
674 __ pushq(type_arguments); | 736 __ pushq(type_arguments); |
675 __ pushq(instantiator_type_arguments); | 737 __ pushq(instantiator_type_arguments); |
676 compiler->GenerateCallRuntime(cid(), | 738 compiler->GenerateCallRuntime(cid(), |
677 token_index(), | 739 token_index(), |
678 try_index(), | 740 try_index(), |
679 kAllocateObjectWithBoundsCheckRuntimeEntry); | 741 kAllocateObjectWithBoundsCheckRuntimeEntry); |
680 // Pop instantiator type arguments, type arguments, class, and | 742 // Pop instantiator type arguments, type arguments, class, and |
681 // source location. | 743 // source location. |
682 __ Drop(4); | 744 __ Drop(4); |
683 __ popq(result); // Pop new instance. | 745 __ popq(result); // Pop new instance. |
684 } | 746 } |
685 | 747 |
686 | 748 |
687 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 749 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
688 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 750 return LocationSummary::Make(1, Location::RequiresRegister()); |
689 } | 751 } |
690 | 752 |
691 | 753 |
692 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 754 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
693 Register obj = locs()->in(0).reg(); | 755 Register obj = locs()->in(0).reg(); |
694 Register result = locs()->out().reg(); | 756 Register result = locs()->out().reg(); |
695 | 757 |
696 __ movq(result, FieldAddress(obj, offset_in_bytes())); | 758 __ movq(result, FieldAddress(obj, offset_in_bytes())); |
697 } | 759 } |
698 | 760 |
699 | 761 |
700 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const { | 762 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const { |
701 return MakeSimpleLocationSummary(2, Location::SameAsFirstInput()); | 763 return LocationSummary::Make(2, Location::SameAsFirstInput()); |
702 } | 764 } |
703 | 765 |
704 | 766 |
705 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 767 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
706 Register value_reg = locs()->in(0).reg(); | 768 Register value_reg = locs()->in(0).reg(); |
707 Register dest_reg = locs()->in(1).reg(); | 769 Register dest_reg = locs()->in(1).reg(); |
708 ASSERT(value_reg == locs()->out().reg()); | 770 ASSERT(value_reg == locs()->out().reg()); |
709 | 771 |
710 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), | 772 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
711 value_reg); | 773 value_reg); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 const ExternalLabel label("alloc_context", | 981 const ExternalLabel label("alloc_context", |
920 StubCode::AllocateContextEntryPoint()); | 982 StubCode::AllocateContextEntryPoint()); |
921 compiler->GenerateCall(token_index(), | 983 compiler->GenerateCall(token_index(), |
922 try_index(), | 984 try_index(), |
923 &label, | 985 &label, |
924 PcDescriptors::kOther); | 986 PcDescriptors::kOther); |
925 } | 987 } |
926 | 988 |
927 | 989 |
928 LocationSummary* ChainContextComp::MakeLocationSummary() const { | 990 LocationSummary* ChainContextComp::MakeLocationSummary() const { |
929 return MakeSimpleLocationSummary(1, Location::NoLocation()); | 991 return LocationSummary::Make(1, Location::NoLocation()); |
930 } | 992 } |
931 | 993 |
932 | 994 |
933 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 995 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
934 Register context_value = locs()->in(0).reg(); | 996 Register context_value = locs()->in(0).reg(); |
935 | 997 |
936 // Chain the new context in context_value to its parent in CTX. | 998 // Chain the new context in context_value to its parent in CTX. |
937 __ StoreIntoObject(context_value, | 999 __ StoreIntoObject(context_value, |
938 FieldAddress(context_value, Context::parent_offset()), | 1000 FieldAddress(context_value, Context::parent_offset()), |
939 CTX); | 1001 CTX); |
940 // Set new context as current context. | 1002 // Set new context as current context. |
941 __ movq(CTX, context_value); | 1003 __ movq(CTX, context_value); |
942 } | 1004 } |
943 | 1005 |
944 | 1006 |
945 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 1007 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
946 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 1008 return LocationSummary::Make(1, Location::RequiresRegister()); |
947 } | 1009 } |
948 | 1010 |
949 | 1011 |
950 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1012 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
951 Register context_value = locs()->in(0).reg(); | 1013 Register context_value = locs()->in(0).reg(); |
952 Register result = locs()->out().reg(); | 1014 Register result = locs()->out().reg(); |
953 | 1015 |
954 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1016 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
955 __ pushq(context_value); | 1017 __ pushq(context_value); |
956 compiler->GenerateCallRuntime(cid(), | 1018 compiler->GenerateCallRuntime(cid(), |
957 token_index(), | 1019 token_index(), |
958 try_index(), | 1020 try_index(), |
959 kCloneContextRuntimeEntry); | 1021 kCloneContextRuntimeEntry); |
960 __ popq(result); // Remove argument. | 1022 __ popq(result); // Remove argument. |
961 __ popq(result); // Get result (cloned context). | 1023 __ popq(result); // Get result (cloned context). |
962 } | 1024 } |
963 | 1025 |
964 | 1026 |
965 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 1027 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
966 return MakeSimpleLocationSummary(0, Location::NoLocation()); | 1028 return LocationSummary::Make(0, Location::NoLocation()); |
967 } | 1029 } |
968 | 1030 |
969 | 1031 |
970 // Restore stack and initialize the two exception variables: | 1032 // Restore stack and initialize the two exception variables: |
971 // exception and stack trace variables. | 1033 // exception and stack trace variables. |
972 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1034 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
973 // Restore RSP from RBP as we are coming from a throw and the code for | 1035 // Restore RSP from RBP as we are coming from a throw and the code for |
974 // popping arguments has not been run. | 1036 // popping arguments has not been run. |
975 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; | 1037 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
976 ASSERT(locals_space_size >= 0); | 1038 ASSERT(locals_space_size >= 0); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 if (locs()->out().reg() != RAX) { | 1253 if (locs()->out().reg() != RAX) { |
1192 __ movq(locs()->out().reg(), RAX); | 1254 __ movq(locs()->out().reg(), RAX); |
1193 } | 1255 } |
1194 } | 1256 } |
1195 | 1257 |
1196 } // namespace dart | 1258 } // namespace dart |
1197 | 1259 |
1198 #undef __ | 1260 #undef __ |
1199 | 1261 |
1200 #endif // defined TARGET_ARCH_X64 | 1262 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |