| 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 |