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

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

Issue 9395016: First part of new ICData infrastructure: use a wrapper object instead of an array. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/code_generator.h" 8 #include "vm/code_generator.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/ic_data.h"
11 #include "vm/object_store.h" 10 #include "vm/object_store.h"
12 #include "vm/pages.h" 11 #include "vm/pages.h"
13 #include "vm/resolver.h" 12 #include "vm/resolver.h"
14 #include "vm/scavenger.h" 13 #include "vm/scavenger.h"
15 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
16 15
17 16
18 #define __ assembler-> 17 #define __ assembler->
19 18
20 namespace dart { 19 namespace dart {
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 314 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
316 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 315 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
317 __ LeaveFrame(); 316 __ LeaveFrame();
318 __ jmp(RAX); 317 __ jmp(RAX);
319 __ int3(); 318 __ int3();
320 } 319 }
321 320
322 321
323 // Lookup for [function-name, arg count] in 'functions_map_'. 322 // Lookup for [function-name, arg count] in 'functions_map_'.
324 // Input parameters (to be treated as read only, unless calling to target!): 323 // Input parameters (to be treated as read only, unless calling to target!):
325 // RBX: ic-data array. 324 // RBX: ic-data.
326 // R10: arguments descriptor array (num_args is first Smi element). 325 // R10: arguments descriptor array (num_args is first Smi element).
327 // Stack: return address, arguments. 326 // Stack: return address, arguments.
328 // If the lookup succeeds we jump to the target method from here, otherwise 327 // If the lookup succeeds we jump to the target method from here, otherwise
329 // we continue in code generated by the caller of 'MegamorphicLookup'. 328 // we continue in code generated by the caller of 'MegamorphicLookup'.
330 static void MegamorphicLookup(Assembler* assembler) { 329 static void MegamorphicLookup(Assembler* assembler) {
331 const Immediate raw_null = 330 const Immediate raw_null =
332 Immediate(reinterpret_cast<intptr_t>(Object::null())); 331 Immediate(reinterpret_cast<intptr_t>(Object::null()));
333 Label class_in_rax, smi_receiver, null_receiver, not_found; 332 Label class_in_rax, smi_receiver, null_receiver, not_found;
334 // Total number of args is the first Smi in args descriptor array (R10). 333 // Total number of args is the first Smi in args descriptor array (R10).
335 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 334 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
(...skipping 28 matching lines...) Expand all
364 // Iterate and search for identical name. 363 // Iterate and search for identical name.
365 __ leaq(R12, FieldAddress(RAX, Array::data_offset())); 364 __ leaq(R12, FieldAddress(RAX, Array::data_offset()));
366 365
367 // R12 is pointing into content of functions_map_ array. 366 // R12 is pointing into content of functions_map_ array.
368 __ Bind(&loop); 367 __ Bind(&loop);
369 __ movq(R13, Address(R12, FunctionsCache::kFunctionName * kWordSize)); 368 __ movq(R13, Address(R12, FunctionsCache::kFunctionName * kWordSize));
370 369
371 __ cmpq(R13, raw_null); 370 __ cmpq(R13, raw_null);
372 __ j(EQUAL, &not_found, Assembler::kNearJump); 371 __ j(EQUAL, &not_found, Assembler::kNearJump);
373 372
374 ASSERT(ICData::kNameIndex == 0); 373 __ cmpq(R13, FieldAddress(RBX, ICData::target_name_offset()));
375 __ cmpq(R13, FieldAddress(RBX, Array::data_offset()));
376 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); 374 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
377 375
378 // Name found, check total argument count and named argument count. 376 // Name found, check total argument count and named argument count.
379 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 377 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
380 // RAX is total argument count as Smi. 378 // RAX is total argument count as Smi.
381 __ movq(R13, Address(R12, FunctionsCache::kArgCount * kWordSize)); 379 __ movq(R13, Address(R12, FunctionsCache::kArgCount * kWordSize));
382 __ cmpq(RAX, R13); // Compare total argument counts. 380 __ cmpq(RAX, R13); // Compare total argument counts.
383 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); 381 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
384 __ subq(RAX, FieldAddress(R10, Array::data_offset() + kWordSize)); 382 __ subq(RAX, FieldAddress(R10, Array::data_offset() + kWordSize));
385 // RAX is named argument count as Smi. 383 // RAX is named argument count as Smi.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 __ movq(Address(RBX, 0), RAX); 425 __ movq(Address(RBX, 0), RAX);
428 __ AddImmediate(RBX, Immediate(kWordSize)); 426 __ AddImmediate(RBX, Immediate(kWordSize));
429 __ AddImmediate(R12, Immediate(-kWordSize)); 427 __ AddImmediate(R12, Immediate(-kWordSize));
430 __ Bind(&loop_condition); 428 __ Bind(&loop_condition);
431 __ decq(R10); 429 __ decq(R10);
432 __ j(POSITIVE, &loop, Assembler::kNearJump); 430 __ j(POSITIVE, &loop, Assembler::kNearJump);
433 } 431 }
434 432
435 433
436 // Input parameters: 434 // Input parameters:
437 // RBX: ic-data array. 435 // RBX: ic-data.
438 // R10: arguments descriptor array (num_args is first Smi element). 436 // R10: arguments descriptor array (num_args is first Smi element).
439 // Note: The receiver object is the first argument to the function being 437 // Note: The receiver object is the first argument to the function being
440 // called, the stub accesses the receiver from this location directly 438 // called, the stub accesses the receiver from this location directly
441 // when trying to resolve the call. 439 // when trying to resolve the call.
442 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 440 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
443 const Immediate raw_null = 441 const Immediate raw_null =
444 Immediate(reinterpret_cast<intptr_t>(Object::null())); 442 Immediate(reinterpret_cast<intptr_t>(Object::null()));
445 443
446 MegamorphicLookup(assembler); 444 MegamorphicLookup(assembler);
447 // Lookup in function_table_ failed, resolve, compile and enter function 445 // Lookup in function_table_ failed, resolve, compile and enter function
448 // into function_table_. 446 // into function_table_.
449 447
450 // Create a stub frame as we are pushing some objects on the stack before 448 // Create a stub frame as we are pushing some objects on the stack before
451 // calling into the runtime. 449 // calling into the runtime.
452 __ EnterFrame(0); 450 __ EnterFrame(0);
453 451
454 // Preserve values across call to resolving. 452 // Preserve values across call to resolving.
455 // Stack at this point: 453 // Stack at this point:
456 // TOS + 0: Saved RBP of previous frame. <== RBP 454 // TOS + 0: Saved RBP of previous frame. <== RBP
457 // TOS + 1: Dart code return address 455 // TOS + 1: Dart code return address
458 // TOS + 2: Last argument of caller. 456 // TOS + 2: Last argument of caller.
459 // .... 457 // ....
460 // Total number of args is the first Smi in args descriptor array (R10). 458 // Total number of args is the first Smi in args descriptor array (R10).
461 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 459 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
462 __ movq(RAX, Address(RSP, RAX, TIMES_4, kWordSize)); // Get receiver. 460 __ movq(RAX, Address(RSP, RAX, TIMES_4, kWordSize)); // Get receiver.
463 __ pushq(R10); // Preserve arguments descriptor array. 461 __ pushq(R10); // Preserve arguments descriptor array.
464 __ pushq(RAX); // Preserve receiver. 462 __ pushq(RAX); // Preserve receiver.
465 __ pushq(RBX); // Preserve ic-data array. 463 __ pushq(RBX); // Preserve ic-data.
466 // First resolve the function to get the function object. 464 // First resolve the function to get the function object.
467 465
468 __ pushq(raw_null); // Setup space on stack for return value. 466 __ pushq(raw_null); // Setup space on stack for return value.
469 __ pushq(RAX); // Push receiver. 467 __ pushq(RAX); // Push receiver.
470 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry); 468 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry);
471 __ popq(RAX); // Remove receiver pushed earlier. 469 __ popq(RAX); // Remove receiver pushed earlier.
472 __ popq(RBX); // Pop returned code object into RBX. 470 __ popq(RBX); // Pop returned code object into RBX.
473 // Pop preserved values 471 // Pop preserved values
474 __ popq(R10); // Restore ic-data array. 472 __ popq(R10); // Restore ic-data.
475 __ popq(RAX); // Restore receiver. 473 __ popq(RAX); // Restore receiver.
476 __ popq(R13); // Restore arguments descriptor array. 474 __ popq(R13); // Restore arguments descriptor array.
477 475
478 __ cmpq(RBX, raw_null); 476 __ cmpq(RBX, raw_null);
479 Label check_implicit_closure; 477 Label check_implicit_closure;
480 __ j(EQUAL, &check_implicit_closure, Assembler::kNearJump); 478 __ j(EQUAL, &check_implicit_closure, Assembler::kNearJump);
481 479
482 // Remove the stub frame as we are about to jump to the dart function. 480 // Remove the stub frame as we are about to jump to the dart function.
483 __ LeaveFrame(); 481 __ LeaveFrame();
484 482
485 __ movq(R10, R13); 483 __ movq(R10, R13);
486 __ movq(RBX, FieldAddress(RBX, Code::instructions_offset())); 484 __ movq(RBX, FieldAddress(RBX, Code::instructions_offset()));
487 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 485 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
488 __ jmp(RBX); 486 __ jmp(RBX);
489 487
490 __ Bind(&check_implicit_closure); 488 __ Bind(&check_implicit_closure);
491 // RAX: receiver. 489 // RAX: receiver.
492 // R10: ic-data array. 490 // R10: ic-data.
493 // RBX: raw_null. 491 // RBX: raw_null.
494 // R13: arguments descriptor array. 492 // R13: arguments descriptor array.
495 // The target function was not found. 493 // The target function was not found.
496 // First check to see if this is a getter function and we are 494 // First check to see if this is a getter function and we are
497 // trying to create a closure of an instance function. 495 // trying to create a closure of an instance function.
498 // Push values that need to be preserved across runtime call. 496 // Push values that need to be preserved across runtime call.
499 __ pushq(RAX); // Preserve receiver. 497 __ pushq(RAX); // Preserve receiver.
500 __ pushq(R10); // Preserve ic-data array. 498 __ pushq(R10); // Preserve ic-data.
501 __ pushq(R13); // Preserve arguments descriptor array. 499 __ pushq(R13); // Preserve arguments descriptor array.
502 500
503 __ pushq(raw_null); // Setup space on stack for return value. 501 __ pushq(raw_null); // Setup space on stack for return value.
504 __ pushq(RAX); // Push receiver. 502 __ pushq(RAX); // Push receiver.
505 __ pushq(R10); // Ic-data array. 503 __ pushq(R10); // Ic-data array.
506 __ CallRuntimeFromStub(kResolveImplicitClosureFunctionRuntimeEntry); 504 __ CallRuntimeFromStub(kResolveImplicitClosureFunctionRuntimeEntry);
507 __ popq(RAX); 505 __ popq(RAX);
508 __ popq(RAX); 506 __ popq(RAX);
509 __ popq(RBX); // Get return value into RBX, might be Closure object. 507 __ popq(RBX); // Get return value into RBX, might be Closure object.
510 508
511 // Pop preserved values. 509 // Pop preserved values.
512 __ popq(R13); // Restore arguments descriptor array. 510 __ popq(R13); // Restore arguments descriptor array.
513 __ popq(R10); // Restore ic-data array. 511 __ popq(R10); // Restore ic-data.
514 __ popq(RAX); // Restore receiver. 512 __ popq(RAX); // Restore receiver.
515 513
516 __ cmpq(RBX, raw_null); 514 __ cmpq(RBX, raw_null);
517 Label check_implicit_closure_through_getter; 515 Label check_implicit_closure_through_getter;
518 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump); 516 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump);
519 517
520 __ movq(RAX, RBX); // Return value is the closure object. 518 __ movq(RAX, RBX); // Return value is the closure object.
521 // Remove the stub frame as we are about return. 519 // Remove the stub frame as we are about return.
522 __ LeaveFrame(); 520 __ LeaveFrame();
523 __ ret(); 521 __ ret();
524 522
525 __ Bind(&check_implicit_closure_through_getter); 523 __ Bind(&check_implicit_closure_through_getter);
526 // RAX: receiver. 524 // RAX: receiver.
527 // R10: ic-data array. 525 // R10: ic-data.
528 // RBX: raw_null. 526 // RBX: raw_null.
529 // R13: arguments descriptor array. 527 // R13: arguments descriptor array.
530 // This is not the case of an instance so invoke the getter of the 528 // This is not the case of an instance so invoke the getter of the
531 // same name and see if we get a closure back which we are then 529 // same name and see if we get a closure back which we are then
532 // supposed to invoke. 530 // supposed to invoke.
533 // Push values that need to be preserved across runtime call. 531 // Push values that need to be preserved across runtime call.
534 __ pushq(RAX); // Preserve receiver. 532 __ pushq(RAX); // Preserve receiver.
535 __ pushq(R10); // Preserve ic-data array. 533 __ pushq(R10); // Preserve ic-data.
536 __ pushq(R13); // Preserve arguments descriptor array. 534 __ pushq(R13); // Preserve arguments descriptor array.
537 535
538 __ pushq(raw_null); // Setup space on stack for return value. 536 __ pushq(raw_null); // Setup space on stack for return value.
539 __ pushq(RAX); // Push receiver. 537 __ pushq(RAX); // Push receiver.
540 __ pushq(R10); // Ic-data array. 538 __ pushq(R10); // Ic-data array.
541 __ CallRuntimeFromStub(kResolveImplicitClosureThroughGetterRuntimeEntry); 539 __ CallRuntimeFromStub(kResolveImplicitClosureThroughGetterRuntimeEntry);
542 __ popq(R10); // Pop argument. 540 __ popq(R10); // Pop argument.
543 __ popq(RAX); // Pop argument. 541 __ popq(RAX); // Pop argument.
544 __ popq(RBX); // get return value into RBX, might be Closure object. 542 __ popq(RBX); // get return value into RBX, might be Closure object.
545 543
546 // Pop preserved values. 544 // Pop preserved values.
547 __ popq(R13); // Restore arguments descriptor array. 545 __ popq(R13); // Restore arguments descriptor array.
548 __ popq(R10); // Restore ic-data array. 546 __ popq(R10); // Restore ic-data.
549 __ popq(RAX); // Restore receiver. 547 __ popq(RAX); // Restore receiver.
550 548
551 __ cmpq(RBX, raw_null); 549 __ cmpq(RBX, raw_null);
552 Label function_not_found; 550 Label function_not_found;
553 __ j(EQUAL, &function_not_found); 551 __ j(EQUAL, &function_not_found);
554 552
555 // RBX: Closure object. 553 // RBX: Closure object.
556 // R13: Arguments descriptor array. 554 // R13: Arguments descriptor array.
557 __ pushq(raw_null); // Setup space on stack for result from invoking Closure. 555 __ pushq(raw_null); // Setup space on stack for result from invoking Closure.
558 __ pushq(RBX); // Closure object. 556 __ pushq(RBX); // Closure object.
(...skipping 20 matching lines...) Expand all
579 __ popq(RAX); // Get result into RAX. 577 __ popq(RAX); // Get result into RAX.
580 578
581 // Remove the stub frame as we are about to return. 579 // Remove the stub frame as we are about to return.
582 __ LeaveFrame(); 580 __ LeaveFrame();
583 __ ret(); 581 __ ret();
584 582
585 __ Bind(&function_not_found); 583 __ Bind(&function_not_found);
586 // The target function was not found, so invoke method 584 // The target function was not found, so invoke method
587 // "void noSuchMethod(function_name, args_array)". 585 // "void noSuchMethod(function_name, args_array)".
588 // RAX: receiver. 586 // RAX: receiver.
589 // R10: ic-data array. 587 // R10: ic-data.
590 // RBX: raw_null. 588 // RBX: raw_null.
591 // R13: argument descriptor array. 589 // R13: argument descriptor array.
592 590
593 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. 591 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod.
594 __ pushq(RAX); // Receiver. 592 __ pushq(RAX); // Receiver.
595 __ pushq(R10); // IC-data array. 593 __ pushq(R10); // IC-data array.
596 __ pushq(R13); // Argument descriptor array. 594 __ pushq(R13); // Argument descriptor array.
597 __ movq(R13, FieldAddress(R13, Array::data_offset())); 595 __ movq(R13, FieldAddress(R13, Array::data_offset()));
598 __ SmiUntag(R13); 596 __ SmiUntag(R13);
599 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. 597 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver.
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 } 1472 }
1475 1473
1476 1474
1477 // Called for invoking noSuchMethod function from the entry code of a dart 1475 // Called for invoking noSuchMethod function from the entry code of a dart
1478 // function after an error in passed named arguments is detected. 1476 // function after an error in passed named arguments is detected.
1479 // Input parameters: 1477 // Input parameters:
1480 // RBP : points to previous frame pointer. 1478 // RBP : points to previous frame pointer.
1481 // RBP + 8 : points to return address. 1479 // RBP + 8 : points to return address.
1482 // RBP + 16 : address of last argument (arg n-1). 1480 // RBP + 16 : address of last argument (arg n-1).
1483 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). 1481 // RBP + 16 + 8*(n-1) : address of first argument (arg 0).
1484 // RBX : ic-data array. 1482 // RBX : ic-data.
1485 // R10 : arguments descriptor array. 1483 // R10 : arguments descriptor array.
1486 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1484 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1487 // The target function was not found, so invoke method 1485 // The target function was not found, so invoke method
1488 // "void noSuchMethod(function_name, Array arguments)". 1486 // "void noSuchMethod(function_name, Array arguments)".
1489 // TODO(regis): For now, we simply pass the actual arguments, both positional 1487 // TODO(regis): For now, we simply pass the actual arguments, both positional
1490 // and named, as the argument array. This is not correct if out-of-order 1488 // and named, as the argument array. This is not correct if out-of-order
1491 // named arguments were passed. 1489 // named arguments were passed.
1492 // The signature of the "noSuchMethod" method has to change from 1490 // The signature of the "noSuchMethod" method has to change from
1493 // noSuchMethod(String name, Array arguments) to something like 1491 // noSuchMethod(String name, Array arguments) to something like
1494 // noSuchMethod(InvocationMirror call). 1492 // noSuchMethod(InvocationMirror call).
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 __ popq(RAX); // Get result into RAX. 1528 __ popq(RAX); // Get result into RAX.
1531 1529
1532 // Remove the stub frame as we are about to return. 1530 // Remove the stub frame as we are about to return.
1533 __ LeaveFrame(); 1531 __ LeaveFrame();
1534 __ ret(); 1532 __ ret();
1535 } 1533 }
1536 1534
1537 1535
1538 1536
1539 // Generate inline cache check for 'num_args'. 1537 // Generate inline cache check for 'num_args'.
1540 // RBX: Inline cache data array. 1538 // RBX: Inline cache data object.
1541 // R10: Arguments array. 1539 // R10: Arguments array.
1542 // TOS(0): return address 1540 // TOS(0): return address
1543 // Control flow: 1541 // Control flow:
1544 // - If receiver is null -> jump to IC miss. 1542 // - If receiver is null -> jump to IC miss.
1545 // - If receiver is Smi -> load Smi class. 1543 // - If receiver is Smi -> load Smi class.
1546 // - If receiver is not-Smi -> load receiver's class. 1544 // - If receiver is not-Smi -> load receiver's class.
1547 // - Check if 'num_args' (including receiver) match any IC data group. 1545 // - Check if 'num_args' (including receiver) match any IC data group.
1548 // - Match found -> jump to target. 1546 // - Match found -> jump to target.
1549 // - Match not found -> jump to IC miss. 1547 // - Match not found -> jump to IC miss.
1550 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1548 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1551 intptr_t num_args) { 1549 intptr_t num_args) {
1552 ASSERT(num_args > 0); 1550 ASSERT(num_args > 0);
1553 // Get receiver. 1551 // Get receiver.
1554 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 1552 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
1555 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. 1553 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi.
1556 1554
1557 Label get_class, ic_miss; 1555 Label get_class, ic_miss;
1558 __ call(&get_class); 1556 __ call(&get_class);
1559 // RAX: receiver's class 1557 // RAX: receiver's class
1560 // RBX: IC data array. 1558 // RBX: IC data array.
1561 1559
1562 #if defined(DEBUG) 1560 #if defined(DEBUG)
1563 { Label ok; 1561 { Label ok;
1564 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1562 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1565 __ movq(RCX, FieldAddress(RBX, 1563 // 'num_args_tested' is stored as an untagged int.
1566 Array::data_offset() + ICData::kNumArgsCheckedIndex * kWordSize)); 1564 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
1567 const Immediate value = 1565 __ cmpq(RCX, Immediate(num_args));
1568 Immediate(reinterpret_cast<int64_t>(Smi::New(num_args)));
1569 __ cmpq(RCX, value);
1570 __ j(EQUAL, &ok, Assembler::kNearJump); 1566 __ j(EQUAL, &ok, Assembler::kNearJump);
1571 __ Stop("Incorrect stub for IC data"); 1567 __ Stop("Incorrect stub for IC data");
1572 __ Bind(&ok); 1568 __ Bind(&ok);
1573 } 1569 }
1574 #endif // DEBUG 1570 #endif // DEBUG
1575 1571
1576 // Loop that checks if there is an IC data match. 1572 // Loop that checks if there is an IC data match.
1577 // RAX: receiver's class. 1573 // RAX: receiver's class.
1578 // RBX: IC data array (preserved). 1574 // RBX: IC data object (preserved).
1579 __ leaq(R12, FieldAddress(RBX, 1575 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1580 Array::data_offset() + ICData::kChecksStartIndex * kWordSize)); 1576 // R12: ic_data_array with check entries: classes and target functions.
1581 // R12: pointing to a class to check against (into IC data array). 1577 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1578 // R12: points directly to the first ic data array element.
1582 const Immediate raw_null = 1579 const Immediate raw_null =
1583 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1580 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1584 Label loop, found; 1581 Label loop, found;
1585 if (num_args == 1) { 1582 if (num_args == 1) {
1586 __ Bind(&loop); 1583 __ Bind(&loop);
1587 __ movq(R13, Address(R12, 0)); // Get class to check. 1584 __ movq(R13, Address(R12, 0)); // Get class to check.
1588 __ cmpq(RAX, R13); // Match? 1585 __ cmpq(RAX, R13); // Match?
1589 __ j(EQUAL, &found, Assembler::kNearJump); 1586 __ j(EQUAL, &found, Assembler::kNearJump);
1590 __ addq(R12, Immediate(kWordSize * 2)); // Next element (class + target). 1587 __ addq(R12, Immediate(kWordSize * 2)); // Next element (class + target).
1591 __ cmpq(R13, raw_null); // Done? 1588 __ cmpq(R13, raw_null); // Done?
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 __ popq(R10); 1727 __ popq(R10);
1731 __ popq(RBX); 1728 __ popq(RBX);
1732 __ LeaveFrame(); 1729 __ LeaveFrame();
1733 // Now call the dynamic function. 1730 // Now call the dynamic function.
1734 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); 1731 __ jmp(&StubCode::OneArgCheckInlineCacheLabel());
1735 } 1732 }
1736 1733
1737 } // namespace dart 1734 } // namespace dart
1738 1735
1739 #endif // defined TARGET_ARCH_X64 1736 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698