| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 __ popq(R10); // Restore arguments descriptor array. | 216 __ popq(R10); // Restore arguments descriptor array. |
| 217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 219 __ LeaveFrame(); | 219 __ LeaveFrame(); |
| 220 __ jmp(RAX); | 220 __ jmp(RAX); |
| 221 __ int3(); | 221 __ int3(); |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 // Input parameters: | 225 // Input parameters: |
| 226 // R13: argument count, may be zero. | 226 // R10: smi-tagged argument count, may be zero. |
| 227 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) { | 227 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) { |
| 228 const Immediate raw_null = | 228 const Immediate raw_null = |
| 229 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 229 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 230 | 230 |
| 231 // Allocate array to store arguments of caller. | 231 // Allocate array to store arguments of caller. |
| 232 __ movq(R10, R13); // Arguments array length. | |
| 233 __ SmiTag(R10); // Convert to Smi. | |
| 234 __ movq(RBX, raw_null); // Null element type for raw Array. | 232 __ movq(RBX, raw_null); // Null element type for raw Array. |
| 235 __ call(&StubCode::AllocateArrayLabel()); | 233 __ call(&StubCode::AllocateArrayLabel()); |
| 236 __ SmiUntag(R10); | 234 __ SmiUntag(R10); |
| 237 // RAX: newly allocated array. | 235 // RAX: newly allocated array. |
| 238 // R10: length of the array (was preserved by the stub). | 236 // R10: length of the array (was preserved by the stub). |
| 239 __ pushq(RAX); // Array is in RAX and on top of stack. | 237 __ pushq(RAX); // Array is in RAX and on top of stack. |
| 240 __ leaq(R12, Address(RSP, R10, TIMES_8, arg_offset)); // Addr of first arg. | 238 __ leaq(R12, Address(RSP, R10, TIMES_8, arg_offset)); // Addr of first arg. |
| 241 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); | 239 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); |
| 242 Label loop, loop_condition; | 240 Label loop, loop_condition; |
| 243 __ jmp(&loop_condition, Assembler::kNearJump); | 241 __ jmp(&loop_condition, Assembler::kNearJump); |
| 244 __ Bind(&loop); | 242 __ Bind(&loop); |
| 245 __ movq(RAX, Address(R12, 0)); | 243 __ movq(RAX, Address(R12, 0)); |
| 246 __ movq(Address(RBX, 0), RAX); | 244 __ movq(Address(RBX, 0), RAX); |
| 247 __ AddImmediate(RBX, Immediate(kWordSize)); | 245 __ AddImmediate(RBX, Immediate(kWordSize)); |
| 248 __ AddImmediate(R12, Immediate(-kWordSize)); | 246 __ AddImmediate(R12, Immediate(-kWordSize)); |
| 249 __ Bind(&loop_condition); | 247 __ Bind(&loop_condition); |
| 250 __ decq(R10); | 248 __ decq(R10); |
| 251 __ j(POSITIVE, &loop, Assembler::kNearJump); | 249 __ j(POSITIVE, &loop, Assembler::kNearJump); |
| 252 } | 250 } |
| 253 | 251 |
| 254 | 252 |
| 255 // Input parameters: | 253 // Input parameters: |
| 256 // RBX: ic-data. | 254 // RBX: ic-data. |
| 257 // R10: arguments descriptor array. | 255 // R10: arguments descriptor array. |
| 258 // Note: The receiver object is the first argument to the function being | 256 // Note: The receiver object is the first argument to the function being |
| 259 // called, the stub accesses the receiver from this location directly | 257 // called, the stub accesses the receiver from this location directly |
| 260 // when trying to resolve the call. | 258 // when trying to resolve the call. |
| 261 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | 259 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
| 260 AssemblerMacros::EnterStubFrame(assembler); |
| 261 |
| 262 const Immediate raw_null = | 262 const Immediate raw_null = |
| 263 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 263 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 264 __ pushq(raw_null); // Space for the return value. |
| 264 | 265 |
| 265 // Create a stub frame as we are pushing some objects on the stack before | 266 // Push the receiver as an argument. Load the smi-tagged argument |
| 266 // calling into the runtime. | 267 // count into R13 to index the receiver in the stack. There are |
| 267 AssemblerMacros::EnterStubFrame(assembler); | 268 // three words (null, stub's pc marker, saved fp) above the return |
| 269 // address. |
| 270 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 271 __ pushq(Address(RSP, R13, TIMES_4, (3 * kWordSize))); |
| 268 | 272 |
| 269 // Preserve values across call to resolving. | 273 __ pushq(RBX); // Pass IC data object. |
| 270 // Stack at this point: | 274 __ pushq(R10); // Pass arguments descriptor array. |
| 271 // TOS + 0: PC marker => RawInstruction object. | |
| 272 // TOS + 1: Saved RBP of previous frame. <== RBP | |
| 273 // TOS + 2: Dart code return address | |
| 274 // TOS + 3: Last argument of caller. | |
| 275 // .... | |
| 276 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | |
| 277 __ movq(RAX, Address(RBP, RAX, TIMES_4, kWordSize)); // Get receiver. | |
| 278 // RAX: receiver. | |
| 279 // RBX: ic-data. | |
| 280 // R10: arguments descriptor array. | |
| 281 // The target function was not found. | |
| 282 // First check to see if this is a getter function and we are | |
| 283 // trying to create a closure of an instance function. | |
| 284 // Push values that need to be preserved across runtime call. | |
| 285 __ pushq(RAX); // Preserve receiver. | |
| 286 __ pushq(RBX); // Preserve ic-data. | |
| 287 __ pushq(R10); // Preserve arguments descriptor array. | |
| 288 | 275 |
| 289 __ pushq(raw_null); // Setup space on stack for return value. | 276 // Pass the call's arguments array. |
| 290 __ pushq(RAX); // Push receiver. | 277 __ movq(R10, R13); // Smi-tagged arguments array length. |
| 291 __ pushq(RBX); // Ic-data array. | 278 PushArgumentsArray(assembler, (7 * kWordSize)); |
| 292 __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry); | 279 // Stack layout explaining "(7 * kWordSize)" offset. |
| 293 __ popq(RAX); | |
| 294 __ popq(RAX); | |
| 295 __ popq(RCX); // Get return value into RCX, might be Closure object. | |
| 296 | |
| 297 // Pop preserved values. | |
| 298 __ popq(R10); // Restore arguments descriptor array. | |
| 299 __ popq(RBX); // Restore ic-data. | |
| 300 __ popq(RAX); // Restore receiver. | |
| 301 | |
| 302 __ cmpq(RCX, raw_null); | |
| 303 Label check_implicit_closure_through_getter; | |
| 304 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump); | |
| 305 | |
| 306 __ movq(RAX, RCX); // Return value is the closure object. | |
| 307 // Remove the stub frame as we are about return. | |
| 308 __ LeaveFrame(); | |
| 309 __ ret(); | |
| 310 | |
| 311 __ Bind(&check_implicit_closure_through_getter); | |
| 312 // RAX: receiver. | |
| 313 // RBX: ic-data. | |
| 314 // R10: arguments descriptor array. | |
| 315 // This is not the case of an instance so invoke the getter of the | |
| 316 // same name and see if we get a closure back which we are then | |
| 317 // supposed to invoke. | |
| 318 // Push values that need to be preserved across runtime call. | |
| 319 __ pushq(RAX); // Preserve receiver. | |
| 320 __ pushq(RBX); // Preserve ic-data. | |
| 321 __ pushq(R10); // Preserve arguments descriptor array. | |
| 322 | |
| 323 __ pushq(raw_null); // Setup space on stack for return value. | |
| 324 __ pushq(RAX); // Push receiver. | |
| 325 __ pushq(RBX); // Ic-data array. | |
| 326 __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry); | |
| 327 __ popq(RAX); // Pop argument. | |
| 328 __ popq(RAX); // Pop argument. | |
| 329 __ popq(RCX); // get return value into RCX, might be Closure object. | |
| 330 | |
| 331 // Pop preserved values. | |
| 332 __ popq(R10); // Restore arguments descriptor array. | |
| 333 __ popq(RBX); // Restore ic-data. | |
| 334 __ popq(RAX); // Restore receiver. | |
| 335 | |
| 336 __ cmpq(RCX, raw_null); | |
| 337 Label function_not_found; | |
| 338 __ j(EQUAL, &function_not_found); | |
| 339 | |
| 340 // RCX: Closure object. | |
| 341 // R10: Arguments descriptor array. | |
| 342 __ pushq(raw_null); // Setup space on stack for result from invoking Closure. | |
| 343 __ pushq(RCX); // Closure object. | |
| 344 __ pushq(R10); // Arguments descriptor. | |
| 345 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | |
| 346 __ SmiUntag(R13); // Arguments array length, including the original receiver. | |
| 347 PushArgumentsArray(assembler, (kWordSize * 6)); | |
| 348 // Stack layout explaining "(kWordSize * 6)" offset. | |
| 349 // TOS + 0: Argument array. | |
| 350 // TOS + 1: Arguments descriptor array. | |
| 351 // TOS + 2: Closure object. | |
| 352 // TOS + 3: Place for result from closure function. | |
| 353 // TOS + 4: PC marker => RawInstruction object. | |
| 354 // TOS + 5: Saved RBP of previous frame. <== RBP | |
| 355 // TOS + 6: Dart code return address | |
| 356 // TOS + 7: Last argument of caller. | |
| 357 // .... | |
| 358 | |
| 359 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); | |
| 360 // Remove arguments. | |
| 361 __ popq(RAX); | |
| 362 __ popq(RAX); | |
| 363 __ popq(RAX); | |
| 364 __ popq(RAX); // Get result into RAX. | |
| 365 | |
| 366 // Remove the stub frame as we are about to return. | |
| 367 __ LeaveFrame(); | |
| 368 __ ret(); | |
| 369 | |
| 370 __ Bind(&function_not_found); | |
| 371 // The target function was not found, so invoke method | |
| 372 // "dynamic noSuchMethod(InvocationMirror invocation)". | |
| 373 // RAX: receiver. | |
| 374 // RBX: ic-data. | |
| 375 // R10: arguments descriptor array. | |
| 376 | |
| 377 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | |
| 378 __ pushq(RAX); // Receiver. | |
| 379 __ pushq(RBX); // IC-data array. | |
| 380 __ pushq(R10); // Arguments descriptor array. | |
| 381 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | |
| 382 __ SmiUntag(R13); // Arguments array length, including the original receiver. | |
| 383 // See stack layout below explaining "wordSize * 7" offset. | |
| 384 PushArgumentsArray(assembler, (kWordSize * 7)); | |
| 385 | |
| 386 // Stack: | |
| 387 // TOS + 0: Arguments array. | 280 // TOS + 0: Arguments array. |
| 388 // TOS + 1: Arguments descriptor array. | 281 // TOS + 1: Arguments descriptor array. |
| 389 // TOS + 2: IC-data array. | 282 // TOS + 2: IC data object. |
| 390 // TOS + 3: Receiver. | 283 // TOS + 3: Receiver. |
| 391 // TOS + 4: Place for result from noSuchMethod. | 284 // TOS + 4: Space for the result of the runtime call. |
| 392 // TOS + 5: PC marker => RawInstruction object. | 285 // TOS + 5: Stub's PC marker (0) |
| 393 // TOS + 6: Saved RBP of previous frame. <== RBP | 286 // TOS + 6: Saved FP |
| 394 // TOS + 7: Dart code return address | 287 // TOS + 7: Dart code return address |
| 395 // TOS + 8: Last argument of caller. | 288 // TOS + 8: Last argument of caller. |
| 396 // .... | 289 // .... |
| 397 | 290 |
| 398 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 291 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); |
| 399 // Remove arguments. | 292 // Remove arguments. |
| 400 __ popq(RAX); | 293 __ popq(RAX); |
| 401 __ popq(RAX); | 294 __ popq(RAX); |
| 402 __ popq(RAX); | 295 __ popq(RAX); |
| 403 __ popq(RAX); | 296 __ popq(RAX); |
| 404 __ popq(RAX); // Get result into RAX. | 297 __ popq(RAX); // Get result into RAX. |
| 405 | |
| 406 // Remove the stub frame as we are about to return. | |
| 407 __ LeaveFrame(); | 298 __ LeaveFrame(); |
| 408 __ ret(); | 299 __ ret(); |
| 409 } | 300 } |
| 410 | 301 |
| 411 | 302 |
| 412 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 303 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
| 413 intptr_t deopt_reason, | 304 intptr_t deopt_reason, |
| 414 uword saved_registers_address); | 305 uword saved_registers_address); |
| 415 | 306 |
| 416 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); | 307 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 416 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
| 526 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. | 417 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. |
| 527 } | 418 } |
| 528 | 419 |
| 529 | 420 |
| 530 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 421 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
| 531 AssemblerMacros::EnterStubFrame(assembler); | 422 AssemblerMacros::EnterStubFrame(assembler); |
| 532 // Load the receiver into RAX. The argument count in the arguments | 423 // Load the receiver into RAX. The argument count in the arguments |
| 533 // descriptor in R10 is a smi. | 424 // descriptor in R10 is a smi. |
| 534 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 425 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 535 // Two words (return addres, saved fp) in the stack above the last argument. | 426 // Two words (saved fp, stub's pc marker) in the stack above the return |
| 427 // address. |
| 536 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); | 428 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); |
| 537 // Preserve IC data and arguments descriptor. | 429 // Preserve IC data and arguments descriptor. |
| 538 __ pushq(RBX); | 430 __ pushq(RBX); |
| 539 __ pushq(R10); | 431 __ pushq(R10); |
| 540 | 432 |
| 541 const Immediate raw_null = | 433 const Immediate raw_null = |
| 542 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); | 434 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); |
| 543 __ pushq(raw_null); // Space for the result of the runtime call. | 435 __ pushq(raw_null); // Space for the result of the runtime call. |
| 544 __ pushq(RAX); // Receiver. | 436 __ pushq(RAX); // Receiver. |
| 545 __ pushq(RBX); // IC data. | 437 __ pushq(RBX); // IC data. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 // R13: non-closure object. | 663 // R13: non-closure object. |
| 772 // R10: arguments descriptor array. | 664 // R10: arguments descriptor array. |
| 773 | 665 |
| 774 // Create a stub frame as we are pushing some objects on the stack before | 666 // Create a stub frame as we are pushing some objects on the stack before |
| 775 // calling into the runtime. | 667 // calling into the runtime. |
| 776 AssemblerMacros::EnterStubFrame(assembler); | 668 AssemblerMacros::EnterStubFrame(assembler); |
| 777 | 669 |
| 778 __ pushq(raw_null); // Setup space on stack for result from call. | 670 __ pushq(raw_null); // Setup space on stack for result from call. |
| 779 __ pushq(R13); // Non-closure object. | 671 __ pushq(R13); // Non-closure object. |
| 780 __ pushq(R10); // Arguments descriptor. | 672 __ pushq(R10); // Arguments descriptor. |
| 781 // Load num_args. | 673 // Load smi-tagged arguments array length, including the non-closure. |
| 782 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 674 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 783 __ SmiUntag(R13); // Arguments array length, including the non-closure. | |
| 784 // See stack layout below explaining "wordSize * 6" offset. | 675 // See stack layout below explaining "wordSize * 6" offset. |
| 785 PushArgumentsArray(assembler, (kWordSize * 6)); | 676 PushArgumentsArray(assembler, (kWordSize * 6)); |
| 786 | 677 |
| 787 // Stack: | 678 // Stack: |
| 788 // TOS + 0: Argument array. | 679 // TOS + 0: Argument array. |
| 789 // TOS + 1: Arguments descriptor array. | 680 // TOS + 1: Arguments descriptor array. |
| 790 // TOS + 2: Non-closure object. | 681 // TOS + 2: Non-closure object. |
| 791 // TOS + 3: Place for result from the call. | 682 // TOS + 3: Place for result from the call. |
| 792 // TOS + 4: PC marker => RawInstruction object. | 683 // TOS + 4: PC marker => RawInstruction object. |
| 793 // TOS + 5: Saved RBP of previous frame. <== RBP | 684 // TOS + 5: Saved RBP of previous frame. <== RBP |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1438 // RBP + 16 : address of last argument (arg n-1). | 1329 // RBP + 16 : address of last argument (arg n-1). |
| 1439 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). | 1330 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). |
| 1440 // RBX : ic-data. | 1331 // RBX : ic-data. |
| 1441 // R10 : arguments descriptor array. | 1332 // R10 : arguments descriptor array. |
| 1442 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1333 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
| 1443 // The target function was not found, so invoke method | 1334 // The target function was not found, so invoke method |
| 1444 // "dynamic noSuchMethod(InvocationMirror invocation)". | 1335 // "dynamic noSuchMethod(InvocationMirror invocation)". |
| 1445 const Immediate raw_null = | 1336 const Immediate raw_null = |
| 1446 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1337 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1447 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1338 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 1448 __ SmiUntag(R13); | 1339 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver. |
| 1449 __ movq(RAX, Address(RBP, R13, TIMES_8, kWordSize)); // Get receiver. | |
| 1450 | 1340 |
| 1451 // Create a stub frame. | 1341 // Create a stub frame. |
| 1452 AssemblerMacros::EnterStubFrame(assembler); | 1342 AssemblerMacros::EnterStubFrame(assembler); |
| 1453 | 1343 |
| 1454 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 1344 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
| 1455 __ pushq(RAX); // Receiver. | 1345 __ pushq(RAX); // Receiver. |
| 1456 __ pushq(RBX); // IC data array. | 1346 __ pushq(RBX); // IC data array. |
| 1457 __ pushq(R10); // Arguments descriptor array. | 1347 __ pushq(R10); // Arguments descriptor array. |
| 1458 // R13: Arguments array length, including the receiver. | 1348 |
| 1349 __ movq(R10, R13); // Smi-tagged arguments array length. |
| 1459 // See stack layout below explaining "wordSize * 10" offset. | 1350 // See stack layout below explaining "wordSize * 10" offset. |
| 1460 PushArgumentsArray(assembler, (kWordSize * 10)); | 1351 PushArgumentsArray(assembler, (kWordSize * 10)); |
| 1461 | 1352 |
| 1462 // Stack: | 1353 // Stack: |
| 1463 // TOS + 0: Argument array. | 1354 // TOS + 0: Argument array. |
| 1464 // TOS + 1: Arguments descriptor array. | 1355 // TOS + 1: Arguments descriptor array. |
| 1465 // TOS + 2: Ic-data array. | 1356 // TOS + 2: Ic-data array. |
| 1466 // TOS + 3: Receiver. | 1357 // TOS + 3: Receiver. |
| 1467 // TOS + 4: Place for result from noSuchMethod. | 1358 // TOS + 4: Place for result from noSuchMethod. |
| 1468 // TOS + 5: PC marker => RawInstruction object. | 1359 // TOS + 5: PC marker => RawInstruction object. |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2175 __ cmpq(left, right); | 2066 __ cmpq(left, right); |
| 2176 __ Bind(&done); | 2067 __ Bind(&done); |
| 2177 __ popq(right); | 2068 __ popq(right); |
| 2178 __ popq(left); | 2069 __ popq(left); |
| 2179 __ ret(); | 2070 __ ret(); |
| 2180 } | 2071 } |
| 2181 | 2072 |
| 2182 } // namespace dart | 2073 } // namespace dart |
| 2183 | 2074 |
| 2184 #endif // defined TARGET_ARCH_X64 | 2075 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |