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 | 19 DECLARE_FLAG(bool, optimization_counter_threshold); |
20 static LocationSummary* MakeSimpleLocationSummary( | 20 DECLARE_FLAG(bool, trace_functions); |
21 intptr_t input_count, Location out) { | |
22 LocationSummary* summary = new LocationSummary(input_count, 0); | |
23 for (intptr_t i = 0; i < input_count; i++) { | |
24 summary->set_in(i, Location::RequiresRegister()); | |
25 } | |
26 summary->set_out(out); | |
27 return summary; | |
28 } | |
29 | 21 |
30 | 22 |
31 // True iff. the arguments to a call will be properly pushed and can | 23 // True iff. the arguments to a call will be properly pushed and can |
32 // be popped after the call. | 24 // be popped after the call. |
33 template <typename T> static bool VerifyCallComputation(T* comp) { | 25 template <typename T> static bool VerifyCallComputation(T* comp) { |
34 // Argument values should be consecutive temps. | 26 // Argument values should be consecutive temps. |
35 // | 27 // |
36 // TODO(kmillikin): implement stack height tracking so we can also assert | 28 // TODO(kmillikin): implement stack height tracking so we can also assert |
37 // they are on top of the stack. | 29 // they are on top of the stack. |
38 intptr_t previous = -1; | 30 intptr_t previous = -1; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // comparison with true fails. | 111 // comparison with true fails. |
120 __ j(EQUAL, compiler->GetBlockLabel(true_successor())); | 112 __ j(EQUAL, compiler->GetBlockLabel(true_successor())); |
121 } else { | 113 } else { |
122 // If the next block is the true sucessor we negate comparison and fall | 114 // If the next block is the true sucessor we negate comparison and fall |
123 // through to it. | 115 // through to it. |
124 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor())); | 116 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor())); |
125 } | 117 } |
126 } | 118 } |
127 | 119 |
128 | 120 |
| 121 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
| 122 const intptr_t kNumInputs = 1; |
| 123 const intptr_t kNumTemps = 1; |
| 124 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 125 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 126 locs->set_temp(0, Location::RequiresRegister()); |
| 127 return locs; |
| 128 } |
| 129 |
| 130 |
| 131 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 132 Register result = locs()->in(0).reg(); |
| 133 Register temp = locs()->temp(0).reg(); |
| 134 ASSERT(result == RAX); |
| 135 if (!compiler->is_optimizing()) { |
| 136 // Count only in unoptimized code. |
| 137 // TODO(srdjan): Replace the counting code with a type feedback |
| 138 // collection and counting stub. |
| 139 const Function& function = |
| 140 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| 141 __ LoadObject(temp, function); |
| 142 __ incq(FieldAddress(temp, Function::usage_counter_offset())); |
| 143 if (CodeGenerator::CanOptimize()) { |
| 144 // Do not optimize if usage count must be reported. |
| 145 __ cmpl(FieldAddress(temp, Function::usage_counter_offset()), |
| 146 Immediate(FLAG_optimization_counter_threshold)); |
| 147 Label not_yet_hot; |
| 148 __ j(LESS_EQUAL, ¬_yet_hot, Assembler::kNearJump); |
| 149 __ pushq(result); // Preserve result. |
| 150 __ pushq(temp); // Argument for runtime: function to optimize. |
| 151 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
| 152 __ popq(temp); // Remove argument. |
| 153 __ popq(result); // Restore result. |
| 154 __ Bind(¬_yet_hot); |
| 155 } |
| 156 } |
| 157 if (FLAG_trace_functions) { |
| 158 __ pushq(result); // Preserve result. |
| 159 const Function& function = |
| 160 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| 161 __ LoadObject(temp, function); |
| 162 __ pushq(temp); |
| 163 compiler->GenerateCallRuntime(AstNode::kNoId, |
| 164 0, |
| 165 CatchClauseNode::kInvalidTryIndex, |
| 166 kTraceFunctionExitRuntimeEntry); |
| 167 __ popq(temp); // Remove argument. |
| 168 __ popq(result); // Restore result. |
| 169 } |
| 170 __ LeaveFrame(); |
| 171 __ ret(); |
| 172 |
| 173 // Generate 8 bytes of NOPs so that the debugger can patch the |
| 174 // return pattern with a call to the debug stub. |
| 175 __ nop(1); |
| 176 __ nop(1); |
| 177 __ nop(1); |
| 178 __ nop(1); |
| 179 __ nop(1); |
| 180 __ nop(1); |
| 181 __ nop(1); |
| 182 __ nop(1); |
| 183 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
| 184 cid(), |
| 185 token_index(), |
| 186 CatchClauseNode::kInvalidTryIndex); |
| 187 } |
| 188 |
| 189 |
129 LocationSummary* CurrentContextComp::MakeLocationSummary() const { | 190 LocationSummary* CurrentContextComp::MakeLocationSummary() const { |
130 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 191 return LocationSummary::Make(0, Location::RequiresRegister()); |
131 } | 192 } |
132 | 193 |
133 | 194 |
134 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 195 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
135 __ movq(locs()->out().reg(), CTX); | 196 __ movq(locs()->out().reg(), CTX); |
136 } | 197 } |
137 | 198 |
138 | 199 |
139 LocationSummary* StoreContextComp::MakeLocationSummary() const { | 200 LocationSummary* StoreContextComp::MakeLocationSummary() const { |
140 LocationSummary* summary = new LocationSummary(1, 0); | 201 LocationSummary* summary = new LocationSummary(1, 0); |
141 summary->set_in(0, Location::RegisterLocation(CTX)); | 202 summary->set_in(0, Location::RegisterLocation(CTX)); |
142 return summary; | 203 return summary; |
143 } | 204 } |
144 | 205 |
145 | 206 |
146 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 207 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
147 // Nothing to do. Context register were loaded by register allocator. | 208 // Nothing to do. Context register were loaded by register allocator. |
148 ASSERT(locs()->in(0).reg() == CTX); | 209 ASSERT(locs()->in(0).reg() == CTX); |
149 } | 210 } |
150 | 211 |
151 | 212 |
152 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 213 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
153 return MakeSimpleLocationSummary(2, Location::SameAsFirstInput()); | 214 return LocationSummary::Make(2, Location::SameAsFirstInput()); |
154 } | 215 } |
155 | 216 |
156 | 217 |
157 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 218 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
158 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 219 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
159 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 220 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
160 | 221 |
161 Register left = locs()->in(0).reg(); | 222 Register left = locs()->in(0).reg(); |
162 Register right = locs()->in(1).reg(); | 223 Register right = locs()->in(1).reg(); |
163 Register result = locs()->out().reg(); | 224 Register result = locs()->out().reg(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 ASSERT(VerifyCallComputation(this)); | 301 ASSERT(VerifyCallComputation(this)); |
241 compiler->EmitStaticCall(token_index(), | 302 compiler->EmitStaticCall(token_index(), |
242 try_index(), | 303 try_index(), |
243 function(), | 304 function(), |
244 ArgumentCount(), | 305 ArgumentCount(), |
245 argument_names()); | 306 argument_names()); |
246 } | 307 } |
247 | 308 |
248 | 309 |
249 LocationSummary* LoadLocalComp::MakeLocationSummary() const { | 310 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
250 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 311 return LocationSummary::Make(0, Location::RequiresRegister()); |
251 } | 312 } |
252 | 313 |
253 | 314 |
254 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 315 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
255 Register result = locs()->out().reg(); | 316 Register result = locs()->out().reg(); |
256 __ movq(result, Address(RBP, local().index() * kWordSize)); | 317 __ movq(result, Address(RBP, local().index() * kWordSize)); |
257 } | 318 } |
258 | 319 |
259 | 320 |
260 LocationSummary* StoreLocalComp::MakeLocationSummary() const { | 321 LocationSummary* StoreLocalComp::MakeLocationSummary() const { |
261 return MakeSimpleLocationSummary(1, Location::SameAsFirstInput()); | 322 return LocationSummary::Make(1, Location::SameAsFirstInput()); |
262 } | 323 } |
263 | 324 |
264 | 325 |
265 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 326 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
266 Register value = locs()->in(0).reg(); | 327 Register value = locs()->in(0).reg(); |
267 Register result = locs()->out().reg(); | 328 Register result = locs()->out().reg(); |
268 ASSERT(result == value); // Assert that register assignment is correct. | 329 ASSERT(result == value); // Assert that register assignment is correct. |
269 __ movq(Address(RBP, local().index() * kWordSize), value); | 330 __ movq(Address(RBP, local().index() * kWordSize), value); |
270 } | 331 } |
271 | 332 |
272 | 333 |
273 LocationSummary* ConstantVal::MakeLocationSummary() const { | 334 LocationSummary* ConstantVal::MakeLocationSummary() const { |
274 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 335 return LocationSummary::Make(0, Location::RequiresRegister()); |
275 } | 336 } |
276 | 337 |
277 | 338 |
278 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { | 339 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { |
279 Register result = locs()->out().reg(); | 340 Register result = locs()->out().reg(); |
280 if (value().IsSmi()) { | 341 if (value().IsSmi()) { |
281 int64_t imm = reinterpret_cast<int64_t>(value().raw()); | 342 int64_t imm = reinterpret_cast<int64_t>(value().raw()); |
282 __ movq(result, Immediate(imm)); | 343 __ movq(result, Immediate(imm)); |
283 } else { | 344 } else { |
284 __ LoadObject(result, value()); | 345 __ LoadObject(result, value()); |
(...skipping 29 matching lines...) Expand all Loading... |
314 compiler->GenerateAssertAssignable(cid(), | 375 compiler->GenerateAssertAssignable(cid(), |
315 token_index(), | 376 token_index(), |
316 try_index(), | 377 try_index(), |
317 dst_type(), | 378 dst_type(), |
318 dst_name()); | 379 dst_name()); |
319 ASSERT(locs()->in(0).reg() == locs()->out().reg()); | 380 ASSERT(locs()->in(0).reg() == locs()->out().reg()); |
320 } | 381 } |
321 | 382 |
322 | 383 |
323 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { | 384 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
324 return MakeSimpleLocationSummary(1, Location::SameAsFirstInput()); | 385 return LocationSummary::Make(1, Location::SameAsFirstInput()); |
325 } | 386 } |
326 | 387 |
327 | 388 |
328 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 389 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
329 Register obj = locs()->in(0).reg(); | 390 Register obj = locs()->in(0).reg(); |
330 Register result = locs()->out().reg(); | 391 Register result = locs()->out().reg(); |
331 | 392 |
332 // Check that the type of the value is allowed in conditional context. | 393 // Check that the type of the value is allowed in conditional context. |
333 // Call the runtime if the object is not bool::true or bool::false. | 394 // Call the runtime if the object is not bool::true or bool::false. |
334 Label done; | 395 Label done; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 kNumArgumentsChecked); | 461 kNumArgumentsChecked); |
401 __ Bind(&done); | 462 __ Bind(&done); |
402 } | 463 } |
403 | 464 |
404 | 465 |
405 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 466 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
406 LocationSummary* locs = new LocationSummary(0, 3); | 467 LocationSummary* locs = new LocationSummary(0, 3); |
407 locs->set_temp(0, Location::RegisterLocation(RAX)); | 468 locs->set_temp(0, Location::RegisterLocation(RAX)); |
408 locs->set_temp(1, Location::RegisterLocation(RBX)); | 469 locs->set_temp(1, Location::RegisterLocation(RBX)); |
409 locs->set_temp(2, Location::RegisterLocation(R10)); | 470 locs->set_temp(2, Location::RegisterLocation(R10)); |
410 locs->set_out(Location::RegisterLocation(RAX)); | 471 locs->set_out(Location::RequiresRegister()); |
411 return locs; | 472 return locs; |
412 } | 473 } |
413 | 474 |
414 | 475 |
415 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 476 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
416 ASSERT(locs()->temp(0).reg() == RAX); | 477 ASSERT(locs()->temp(0).reg() == RAX); |
417 ASSERT(locs()->temp(1).reg() == RBX); | 478 ASSERT(locs()->temp(1).reg() == RBX); |
418 ASSERT(locs()->temp(2).reg() == R10); | 479 ASSERT(locs()->temp(2).reg() == R10); |
419 ASSERT(locs()->out().reg() == RAX); | 480 Register result = locs()->out().reg(); |
420 | 481 |
421 // Push the result place holder initialized to NULL. | 482 // Push the result place holder initialized to NULL. |
422 __ PushObject(Object::ZoneHandle()); | 483 __ PushObject(Object::ZoneHandle()); |
423 // Pass a pointer to the first argument in RAX. | 484 // Pass a pointer to the first argument in RAX. |
424 if (!has_optional_parameters()) { | 485 if (!has_optional_parameters()) { |
425 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); | 486 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); |
426 } else { | 487 } else { |
427 __ leaq(RAX, | 488 __ leaq(RAX, |
428 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 489 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
429 } | 490 } |
430 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 491 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
431 __ movq(R10, Immediate(argument_count())); | 492 __ movq(R10, Immediate(argument_count())); |
432 compiler->GenerateCall(token_index(), | 493 compiler->GenerateCall(token_index(), |
433 try_index(), | 494 try_index(), |
434 &StubCode::CallNativeCFunctionLabel(), | 495 &StubCode::CallNativeCFunctionLabel(), |
435 PcDescriptors::kOther); | 496 PcDescriptors::kOther); |
436 __ popq(RAX); | 497 __ popq(result); |
437 } | 498 } |
438 | 499 |
439 | 500 |
440 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 501 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
441 const intptr_t kNumInputs = 3; | 502 const intptr_t kNumInputs = 3; |
442 return MakeSimpleLocationSummary(kNumInputs, Location::NoLocation()); | 503 return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
443 } | 504 } |
444 | 505 |
445 | 506 |
446 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 507 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
447 Register receiver = locs()->in(0).reg(); | 508 Register receiver = locs()->in(0).reg(); |
448 Register index = locs()->in(1).reg(); | 509 Register index = locs()->in(1).reg(); |
449 Register value = locs()->in(2).reg(); | 510 Register value = locs()->in(2).reg(); |
450 | 511 |
451 const String& function_name = | 512 const String& function_name = |
452 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 513 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
453 | 514 |
454 __ pushq(receiver); | 515 __ pushq(receiver); |
455 __ pushq(index); | 516 __ pushq(index); |
456 __ pushq(value); | 517 __ pushq(value); |
457 const intptr_t kNumArguments = 3; | 518 const intptr_t kNumArguments = 3; |
458 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 519 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
459 compiler->EmitInstanceCall(cid(), | 520 compiler->EmitInstanceCall(cid(), |
460 token_index(), | 521 token_index(), |
461 try_index(), | 522 try_index(), |
462 function_name, | 523 function_name, |
463 kNumArguments, | 524 kNumArguments, |
464 Array::ZoneHandle(), // No optional arguments. | 525 Array::ZoneHandle(), // No optional arguments. |
465 kNumArgsChecked); | 526 kNumArgsChecked); |
466 } | 527 } |
467 | 528 |
468 | 529 |
469 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { | 530 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
470 const intptr_t kNumInputs = 2; | 531 const intptr_t kNumInputs = 2; |
471 return MakeSimpleLocationSummary(kNumInputs, Location::RequiresRegister()); | 532 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
472 return NULL; | 533 return NULL; |
473 } | 534 } |
474 | 535 |
475 | 536 |
476 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 537 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
477 Register receiver = locs()->in(0).reg(); | 538 Register receiver = locs()->in(0).reg(); |
478 Register value = locs()->in(1).reg(); | 539 Register value = locs()->in(1).reg(); |
479 Register result = locs()->out().reg(); | 540 Register result = locs()->out().reg(); |
480 | 541 |
481 // Preserve the value (second argument) under the arguments as the result | 542 // Preserve the value (second argument) under the arguments as the result |
(...skipping 12 matching lines...) Expand all Loading... |
494 function_name, | 555 function_name, |
495 2, | 556 2, |
496 Array::ZoneHandle(), | 557 Array::ZoneHandle(), |
497 1); | 558 1); |
498 __ popq(result); | 559 __ popq(result); |
499 } | 560 } |
500 | 561 |
501 | 562 |
502 LocationSummary* StaticSetterComp::MakeLocationSummary() const { | 563 LocationSummary* StaticSetterComp::MakeLocationSummary() const { |
503 const intptr_t kNumInputs = 1; | 564 const intptr_t kNumInputs = 1; |
504 return MakeSimpleLocationSummary(kNumInputs, Location::RequiresRegister()); | 565 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
505 } | 566 } |
506 | 567 |
507 | 568 |
508 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 569 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
509 Register value = locs()->in(0).reg(); | 570 Register value = locs()->in(0).reg(); |
510 Register result = locs()->out().reg(); | 571 Register result = locs()->out().reg(); |
511 | 572 |
512 // Preserve the argument as the result of the computation, | 573 // Preserve the argument as the result of the computation, |
513 // then call the setter. | 574 // then call the setter. |
514 | 575 |
515 // Duplicate the argument. | 576 // Duplicate the argument. |
516 // TODO(fschneider): Avoid preserving the value if the result is not used. | 577 // TODO(fschneider): Avoid preserving the value if the result is not used. |
517 __ pushq(value); | 578 __ pushq(value); |
518 __ pushq(value); | 579 __ pushq(value); |
519 compiler->EmitStaticCall(token_index(), | 580 compiler->EmitStaticCall(token_index(), |
520 try_index(), | 581 try_index(), |
521 setter_function(), | 582 setter_function(), |
522 1, | 583 1, |
523 Array::ZoneHandle()); | 584 Array::ZoneHandle()); |
524 __ popq(result); | 585 __ popq(result); |
525 } | 586 } |
526 | 587 |
527 | 588 |
528 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { | 589 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
529 // TODO(fschneider): For this instruction the input register may be | 590 // TODO(fschneider): For this instruction the input register may be |
530 // reused for the result (but is not required to) because the input | 591 // reused for the result (but is not required to) because the input |
531 // is not used after the result is defined. We should consider adding | 592 // is not used after the result is defined. We should consider adding |
532 // this information to the input policy. | 593 // this information to the input policy. |
533 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 594 return LocationSummary::Make(1, Location::RequiresRegister()); |
534 } | 595 } |
535 | 596 |
536 | 597 |
537 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 598 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
538 Register instance = locs()->in(0).reg(); | 599 Register instance = locs()->in(0).reg(); |
539 Register result = locs()->out().reg(); | 600 Register result = locs()->out().reg(); |
540 | 601 |
541 __ movq(result, FieldAddress(instance, field().Offset())); | 602 __ movq(result, FieldAddress(instance, field().Offset())); |
542 } | 603 } |
543 | 604 |
544 | 605 |
545 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { | 606 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
546 return MakeSimpleLocationSummary(2, Location::RequiresRegister()); | 607 return LocationSummary::Make(2, Location::RequiresRegister()); |
547 } | 608 } |
548 | 609 |
549 | 610 |
550 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 611 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
551 ASSERT(VerifyValues(instance(), value())); | 612 ASSERT(VerifyValues(instance(), value())); |
552 Register instance = locs()->in(0).reg(); | 613 Register instance = locs()->in(0).reg(); |
553 Register value = locs()->in(1).reg(); | 614 Register value = locs()->in(1).reg(); |
554 Register result = locs()->out().reg(); | 615 Register result = locs()->out().reg(); |
555 | 616 |
556 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()), | 617 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()), |
557 value); | 618 value); |
558 // TODO(fschneider): Consider eliminating this move by specifying a | 619 // TODO(fschneider): Consider eliminating this move by specifying a |
559 // SameAsSecondInput for the result. | 620 // SameAsSecondInput for the result. |
560 if (result != value) { | 621 if (result != value) { |
561 __ movq(result, value); | 622 __ movq(result, value); |
562 } | 623 } |
563 } | 624 } |
564 | 625 |
565 | 626 |
566 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { | 627 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
567 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); | 628 return LocationSummary::Make(0, Location::RequiresRegister()); |
568 } | 629 } |
569 | 630 |
570 | 631 |
571 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 632 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
572 Register result = locs()->out().reg(); | 633 Register result = locs()->out().reg(); |
573 __ LoadObject(result, field()); | 634 __ LoadObject(result, field()); |
574 __ movq(result, FieldAddress(result, Field::value_offset())); | 635 __ movq(result, FieldAddress(result, Field::value_offset())); |
575 } | 636 } |
576 | 637 |
577 | 638 |
(...skipping 10 matching lines...) Expand all Loading... |
588 Register value = locs()->in(0).reg(); | 649 Register value = locs()->in(0).reg(); |
589 Register temp = locs()->temp(0).reg(); | 650 Register temp = locs()->temp(0).reg(); |
590 ASSERT(locs()->out().reg() == value); | 651 ASSERT(locs()->out().reg() == value); |
591 | 652 |
592 __ LoadObject(temp, field()); | 653 __ LoadObject(temp, field()); |
593 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); | 654 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); |
594 } | 655 } |
595 | 656 |
596 | 657 |
597 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { | 658 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { |
598 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 659 return LocationSummary::Make(1, Location::RequiresRegister()); |
599 } | 660 } |
600 | 661 |
601 | 662 |
602 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 663 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
603 Register value = locs()->in(0).reg(); | 664 Register value = locs()->in(0).reg(); |
604 Register result = locs()->out().reg(); | 665 Register result = locs()->out().reg(); |
605 | 666 |
606 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 667 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
607 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 668 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
608 Label done; | 669 Label done; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 compiler->GenerateCall(token_index(), | 764 compiler->GenerateCall(token_index(), |
704 try_index(), | 765 try_index(), |
705 &label, | 766 &label, |
706 PcDescriptors::kOther); | 767 PcDescriptors::kOther); |
707 __ Drop(arguments().length()); // Discard arguments. | 768 __ Drop(arguments().length()); // Discard arguments. |
708 } | 769 } |
709 | 770 |
710 | 771 |
711 LocationSummary* AllocateObjectWithBoundsCheckComp:: | 772 LocationSummary* AllocateObjectWithBoundsCheckComp:: |
712 MakeLocationSummary() const { | 773 MakeLocationSummary() const { |
713 return MakeSimpleLocationSummary(2, Location::RequiresRegister()); | 774 return LocationSummary::Make(2, Location::RequiresRegister()); |
714 } | 775 } |
715 | 776 |
716 | 777 |
717 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 778 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
718 FlowGraphCompiler* compiler) { | 779 FlowGraphCompiler* compiler) { |
719 const Class& cls = Class::ZoneHandle(constructor().owner()); | 780 const Class& cls = Class::ZoneHandle(constructor().owner()); |
720 Register type_arguments = locs()->in(0).reg(); | 781 Register type_arguments = locs()->in(0).reg(); |
721 Register instantiator_type_arguments = locs()->in(1).reg(); | 782 Register instantiator_type_arguments = locs()->in(1).reg(); |
722 Register result = locs()->out().reg(); | 783 Register result = locs()->out().reg(); |
723 | 784 |
724 // Push the result place holder initialized to NULL. | 785 // Push the result place holder initialized to NULL. |
725 __ PushObject(Object::ZoneHandle()); | 786 __ PushObject(Object::ZoneHandle()); |
726 __ pushq(Immediate(Smi::RawValue(token_index()))); | 787 __ pushq(Immediate(Smi::RawValue(token_index()))); |
727 __ PushObject(cls); | 788 __ PushObject(cls); |
728 __ pushq(type_arguments); | 789 __ pushq(type_arguments); |
729 __ pushq(instantiator_type_arguments); | 790 __ pushq(instantiator_type_arguments); |
730 compiler->GenerateCallRuntime(cid(), | 791 compiler->GenerateCallRuntime(cid(), |
731 token_index(), | 792 token_index(), |
732 try_index(), | 793 try_index(), |
733 kAllocateObjectWithBoundsCheckRuntimeEntry); | 794 kAllocateObjectWithBoundsCheckRuntimeEntry); |
734 // Pop instantiator type arguments, type arguments, class, and | 795 // Pop instantiator type arguments, type arguments, class, and |
735 // source location. | 796 // source location. |
736 __ Drop(4); | 797 __ Drop(4); |
737 __ popq(result); // Pop new instance. | 798 __ popq(result); // Pop new instance. |
738 } | 799 } |
739 | 800 |
740 | 801 |
741 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 802 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
742 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 803 return LocationSummary::Make(1, Location::RequiresRegister()); |
743 } | 804 } |
744 | 805 |
745 | 806 |
746 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 807 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
747 Register obj = locs()->in(0).reg(); | 808 Register obj = locs()->in(0).reg(); |
748 Register result = locs()->out().reg(); | 809 Register result = locs()->out().reg(); |
749 | 810 |
750 __ movq(result, FieldAddress(obj, offset_in_bytes())); | 811 __ movq(result, FieldAddress(obj, offset_in_bytes())); |
751 } | 812 } |
752 | 813 |
753 | 814 |
754 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const { | 815 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const { |
755 return MakeSimpleLocationSummary(2, Location::SameAsFirstInput()); | 816 return LocationSummary::Make(2, Location::SameAsFirstInput()); |
756 } | 817 } |
757 | 818 |
758 | 819 |
759 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 820 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
760 Register value_reg = locs()->in(0).reg(); | 821 Register value_reg = locs()->in(0).reg(); |
761 Register dest_reg = locs()->in(1).reg(); | 822 Register dest_reg = locs()->in(1).reg(); |
762 ASSERT(value_reg == locs()->out().reg()); | 823 ASSERT(value_reg == locs()->out().reg()); |
763 | 824 |
764 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), | 825 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), |
765 value_reg); | 826 value_reg); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 const ExternalLabel label("alloc_context", | 1024 const ExternalLabel label("alloc_context", |
964 StubCode::AllocateContextEntryPoint()); | 1025 StubCode::AllocateContextEntryPoint()); |
965 compiler->GenerateCall(token_index(), | 1026 compiler->GenerateCall(token_index(), |
966 try_index(), | 1027 try_index(), |
967 &label, | 1028 &label, |
968 PcDescriptors::kOther); | 1029 PcDescriptors::kOther); |
969 } | 1030 } |
970 | 1031 |
971 | 1032 |
972 LocationSummary* ChainContextComp::MakeLocationSummary() const { | 1033 LocationSummary* ChainContextComp::MakeLocationSummary() const { |
973 return MakeSimpleLocationSummary(1, Location::NoLocation()); | 1034 return LocationSummary::Make(1, Location::NoLocation()); |
974 } | 1035 } |
975 | 1036 |
976 | 1037 |
977 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1038 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
978 Register context_value = locs()->in(0).reg(); | 1039 Register context_value = locs()->in(0).reg(); |
979 | 1040 |
980 // Chain the new context in context_value to its parent in CTX. | 1041 // Chain the new context in context_value to its parent in CTX. |
981 __ StoreIntoObject(context_value, | 1042 __ StoreIntoObject(context_value, |
982 FieldAddress(context_value, Context::parent_offset()), | 1043 FieldAddress(context_value, Context::parent_offset()), |
983 CTX); | 1044 CTX); |
984 // Set new context as current context. | 1045 // Set new context as current context. |
985 __ movq(CTX, context_value); | 1046 __ movq(CTX, context_value); |
986 } | 1047 } |
987 | 1048 |
988 | 1049 |
989 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 1050 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
990 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); | 1051 return LocationSummary::Make(1, Location::RequiresRegister()); |
991 } | 1052 } |
992 | 1053 |
993 | 1054 |
994 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1055 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
995 Register context_value = locs()->in(0).reg(); | 1056 Register context_value = locs()->in(0).reg(); |
996 Register result = locs()->out().reg(); | 1057 Register result = locs()->out().reg(); |
997 | 1058 |
998 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1059 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
999 __ pushq(context_value); | 1060 __ pushq(context_value); |
1000 compiler->GenerateCallRuntime(cid(), | 1061 compiler->GenerateCallRuntime(cid(), |
1001 token_index(), | 1062 token_index(), |
1002 try_index(), | 1063 try_index(), |
1003 kCloneContextRuntimeEntry); | 1064 kCloneContextRuntimeEntry); |
1004 __ popq(result); // Remove argument. | 1065 __ popq(result); // Remove argument. |
1005 __ popq(result); // Get result (cloned context). | 1066 __ popq(result); // Get result (cloned context). |
1006 } | 1067 } |
1007 | 1068 |
1008 | 1069 |
1009 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 1070 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
1010 return MakeSimpleLocationSummary(0, Location::NoLocation()); | 1071 return LocationSummary::Make(0, Location::NoLocation()); |
1011 } | 1072 } |
1012 | 1073 |
1013 | 1074 |
1014 // Restore stack and initialize the two exception variables: | 1075 // Restore stack and initialize the two exception variables: |
1015 // exception and stack trace variables. | 1076 // exception and stack trace variables. |
1016 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1077 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1017 // Restore RSP from RBP as we are coming from a throw and the code for | 1078 // Restore RSP from RBP as we are coming from a throw and the code for |
1018 // popping arguments has not been run. | 1079 // popping arguments has not been run. |
1019 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; | 1080 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
1020 ASSERT(locals_space_size >= 0); | 1081 ASSERT(locals_space_size >= 0); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 if (locs()->out().reg() != RAX) { | 1296 if (locs()->out().reg() != RAX) { |
1236 __ movq(locs()->out().reg(), RAX); | 1297 __ movq(locs()->out().reg(), RAX); |
1237 } | 1298 } |
1238 } | 1299 } |
1239 | 1300 |
1240 } // namespace dart | 1301 } // namespace dart |
1241 | 1302 |
1242 #undef __ | 1303 #undef __ |
1243 | 1304 |
1244 #endif // defined TARGET_ARCH_X64 | 1305 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |