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

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

Issue 8357034: Transitioning to new IC structure: change IC data to include function name; pass IC data instead ... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month 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/ic_stubs_ia32_test.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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_IA32) 6 #if defined(TARGET_ARCH_IA32)
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"
10 #include "vm/object_store.h" 11 #include "vm/object_store.h"
11 #include "vm/pages.h" 12 #include "vm/pages.h"
12 #include "vm/resolver.h" 13 #include "vm/resolver.h"
13 #include "vm/scavenger.h" 14 #include "vm/scavenger.h"
14 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
15 16
16 17
17 #define __ assembler-> 18 #define __ assembler->
18 19
19 namespace dart { 20 namespace dart {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 218
218 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); 219 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset()));
219 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 220 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
220 __ jmp(ECX); 221 __ jmp(ECX);
221 } 222 }
222 223
223 224
224 // Stub is entered after a call but before the callee's frame has been 225 // Stub is entered after a call but before the callee's frame has been
225 // constructed. 226 // constructed.
226 // Handle stack overflow by calling the runtime routine and preserving 227 // Handle stack overflow by calling the runtime routine and preserving
227 // the argument descriptor (EDX) and the name/function object of the call (ECX). 228 // the argument descriptor (EDX) and the ic-data array/function object of
229 // the call (ECX).
228 // The stub must be able to return to callee in case the stack overflow 230 // The stub must be able to return to callee in case the stack overflow
229 // exception is not thrown. 231 // exception is not thrown.
230 void StubCode::GenerateStackOverflowStub(Assembler* assembler) { 232 void StubCode::GenerateStackOverflowStub(Assembler* assembler) {
231 __ EnterFrame(0); 233 __ EnterFrame(0);
232 // Stack at this point: 234 // Stack at this point:
233 // TOS + 0: Saved EBP of previous frame. <== EBP 235 // TOS + 0: Saved EBP of previous frame. <== EBP
234 // TOS + 1: Dart code return address 236 // TOS + 1: Dart code return address
235 // TOS + 2: Last argument of caller. 237 // TOS + 2: Last argument of caller.
236 // .... 238 // ....
237 __ pushl(EDX); // Preserve arguments descriptor array. 239 __ pushl(EDX); // Preserve arguments descriptor array.
238 __ pushl(ECX); // Preserve object (function name or function object). 240 __ pushl(ECX); // Preserve object (ic-data array or function object).
239 __ CallRuntimeFromStub(kStackOverflowRuntimeEntry); 241 __ CallRuntimeFromStub(kStackOverflowRuntimeEntry);
240 __ popl(ECX); // Restore object (function name or function object). 242 __ popl(ECX); // Restore object (ic-data array or function object).
241 __ popl(EDX); // Restore arguments descriptor array. 243 __ popl(EDX); // Restore arguments descriptor array.
242 __ LeaveFrame(); 244 __ LeaveFrame();
243 __ int3(); 245 __ int3();
244 } 246 }
245 247
246 248
247 // Called when number of invocations exceeds 249 // Called when number of invocations exceeds
248 // --optimization_invocation_threshold. 250 // --optimization_invocation_threshold.
249 // EAX: target function. 251 // EAX: target function.
250 // EDX: arguments descriptor array (num_args is first Smi element). 252 // EDX: arguments descriptor array (num_args is first Smi element).
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 285 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
284 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 286 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
285 __ LeaveFrame(); 287 __ LeaveFrame();
286 __ jmp(EAX); 288 __ jmp(EAX);
287 __ int3(); 289 __ int3();
288 } 290 }
289 291
290 292
291 // Lookup for [function-name, arg count] in 'functions_map_'. 293 // Lookup for [function-name, arg count] in 'functions_map_'.
292 // Input parameters (to be treated as read only, unless calling to target!): 294 // Input parameters (to be treated as read only, unless calling to target!):
293 // ECX: function name string. 295 // ECX: ic-data array.
294 // EDX: arguments descriptor array (num_args is first Smi element). 296 // EDX: arguments descriptor array (num_args is first Smi element).
295 // Stack: return address, arguments. 297 // Stack: return address, arguments.
296 // If the lookup succeeds we jump to the target method from here, otherwise 298 // If the lookup succeeds we jump to the target method from here, otherwise
297 // we continue in code generated by the caller of 'MegamorphicLookup'. 299 // we continue in code generated by the caller of 'MegamorphicLookup'.
298 static void MegamorphicLookup(Assembler* assembler) { 300 static void MegamorphicLookup(Assembler* assembler) {
299 const Immediate raw_null = 301 const Immediate raw_null =
300 Immediate(reinterpret_cast<intptr_t>(Object::null())); 302 Immediate(reinterpret_cast<intptr_t>(Object::null()));
301 Label class_in_eax, smi_receiver, null_receiver, not_found; 303 Label class_in_eax, smi_receiver, null_receiver, not_found;
302 // Total number of args is the first Smi in args descriptor array (EDX). 304 // Total number of args is the first Smi in args descriptor array (EDX).
303 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 305 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
(...skipping 28 matching lines...) Expand all
332 // Iterate and search for identical name. 334 // Iterate and search for identical name.
333 __ leal(EBX, FieldAddress(EAX, Array::data_offset())); 335 __ leal(EBX, FieldAddress(EAX, Array::data_offset()));
334 336
335 // EBX is pointing into content of functions_map_ array. 337 // EBX is pointing into content of functions_map_ array.
336 __ Bind(&loop); 338 __ Bind(&loop);
337 __ movl(EDI, Address(EBX, FunctionsCache::kFunctionName * kWordSize)); 339 __ movl(EDI, Address(EBX, FunctionsCache::kFunctionName * kWordSize));
338 340
339 __ cmpl(EDI, raw_null); 341 __ cmpl(EDI, raw_null);
340 __ j(EQUAL, &not_found, Assembler::kNearJump); 342 __ j(EQUAL, &not_found, Assembler::kNearJump);
341 343
342 __ cmpl(EDI, ECX); 344 ASSERT(ICData::kNameIndex == 0);
345 __ cmpl(EDI, FieldAddress(ECX, Array::data_offset()));
343 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); 346 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
344 347
345 // Name found, check total argument count and named argument count. 348 // Name found, check total argument count and named argument count.
346 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 349 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
347 // EAX is total argument count as Smi. 350 // EAX is total argument count as Smi.
348 __ movl(EDI, Address(EBX, FunctionsCache::kArgCount * kWordSize)); 351 __ movl(EDI, Address(EBX, FunctionsCache::kArgCount * kWordSize));
349 __ cmpl(EAX, EDI); // Compare total argument counts. 352 __ cmpl(EAX, EDI); // Compare total argument counts.
350 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); 353 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
351 __ subl(EAX, FieldAddress(EDX, Array::data_offset() + kWordSize)); 354 __ subl(EAX, FieldAddress(EDX, Array::data_offset() + kWordSize));
352 // EAX is named argument count as Smi. 355 // EAX is named argument count as Smi.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 __ movl(Address(ECX, 0), EAX); 398 __ movl(Address(ECX, 0), EAX);
396 __ AddImmediate(ECX, Immediate(kWordSize)); 399 __ AddImmediate(ECX, Immediate(kWordSize));
397 __ AddImmediate(EBX, Immediate(-kWordSize)); 400 __ AddImmediate(EBX, Immediate(-kWordSize));
398 __ Bind(&loop_condition); 401 __ Bind(&loop_condition);
399 __ decl(EDX); 402 __ decl(EDX);
400 __ j(POSITIVE, &loop, Assembler::kNearJump); 403 __ j(POSITIVE, &loop, Assembler::kNearJump);
401 } 404 }
402 405
403 406
404 // Input parameters: 407 // Input parameters:
405 // ECX: function name string. 408 // ECX: ic-data array.
406 // EDX: arguments descriptor array (num_args is first Smi element). 409 // EDX: arguments descriptor array (num_args is first Smi element).
407 // Note: The receiver object is the first argument to the function being 410 // Note: The receiver object is the first argument to the function being
408 // called, the stub accesses the receiver from this location directly 411 // called, the stub accesses the receiver from this location directly
409 // when trying to resolve the call. 412 // when trying to resolve the call.
410 // Uses EDI. 413 // Uses EDI.
411 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 414 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
412 const Immediate raw_null = 415 const Immediate raw_null =
413 Immediate(reinterpret_cast<intptr_t>(Object::null())); 416 Immediate(reinterpret_cast<intptr_t>(Object::null()));
414 417
415 MegamorphicLookup(assembler); 418 MegamorphicLookup(assembler);
416 // Lookup in function_table_ failed, resolve, compile and enter function 419 // Lookup in function_table_ failed, resolve, compile and enter function
417 // into function_table_. 420 // into function_table_.
418 421
419 // Create a stub frame as we are pushing some objects on the stack before 422 // Create a stub frame as we are pushing some objects on the stack before
420 // calling into the runtime. 423 // calling into the runtime.
421 __ EnterFrame(0); 424 __ EnterFrame(0);
422 425
423 // Preserve values across call to resolving. 426 // Preserve values across call to resolving.
424 // Stack at this point: 427 // Stack at this point:
425 // TOS + 0: Saved EBP of previous frame. <== EBP 428 // TOS + 0: Saved EBP of previous frame. <== EBP
426 // TOS + 1: Dart code return address 429 // TOS + 1: Dart code return address
427 // TOS + 2: Last argument of caller. 430 // TOS + 2: Last argument of caller.
428 // .... 431 // ....
429 // Total number of args is the first Smi in args descriptor array (EDX). 432 // Total number of args is the first Smi in args descriptor array (EDX).
430 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 433 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
431 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); // Get receiver. 434 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); // Get receiver.
432 __ pushl(EDX); // Preserve arguments descriptor array. 435 __ pushl(EDX); // Preserve arguments descriptor array.
433 __ pushl(EAX); // Preserve receiver. 436 __ pushl(EAX); // Preserve receiver.
434 __ pushl(ECX); // Preserve function name. 437 __ pushl(ECX); // Preserve ic-data array.
435 // First resolve the function to get the function object. 438 // First resolve the function to get the function object.
436 439
437 // Setup space for return value on stack by pushing smi 0. 440 // Setup space for return value on stack by pushing smi 0.
438 __ pushl(Immediate(0)); 441 __ pushl(Immediate(0));
439 __ pushl(EAX); // Push receiver. 442 __ pushl(EAX); // Push receiver.
440 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry); 443 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry);
441 __ popl(EAX); // Remove receiver pushed earlier. 444 __ popl(EAX); // Remove receiver pushed earlier.
442 __ popl(ECX); // Pop returned code object into ECX. 445 __ popl(ECX); // Pop returned code object into ECX.
443 // Pop preserved values 446 // Pop preserved values
444 __ popl(EDX); // Restore function name. 447 __ popl(EDX); // Restore ic-data array.
445 __ popl(EAX); // Restore receiver. 448 __ popl(EAX); // Restore receiver.
446 __ popl(EDI); // Restore arguments descriptor array. 449 __ popl(EDI); // Restore arguments descriptor array.
447 450
448 __ cmpl(ECX, raw_null); 451 __ cmpl(ECX, raw_null);
449 Label check_implicit_closure; 452 Label check_implicit_closure;
450 __ j(EQUAL, &check_implicit_closure, Assembler::kNearJump); 453 __ j(EQUAL, &check_implicit_closure, Assembler::kNearJump);
451 454
452 // Remove the stub frame as we are about to jump to the dart function. 455 // Remove the stub frame as we are about to jump to the dart function.
453 __ LeaveFrame(); 456 __ LeaveFrame();
454 457
455 __ movl(EDX, EDI); 458 __ movl(EDX, EDI);
456 __ movl(ECX, FieldAddress(ECX, Code::instructions_offset())); 459 __ movl(ECX, FieldAddress(ECX, Code::instructions_offset()));
457 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 460 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
458 __ jmp(ECX); 461 __ jmp(ECX);
459 462
460 __ Bind(&check_implicit_closure); 463 __ Bind(&check_implicit_closure);
461 // EAX: receiver. 464 // EAX: receiver.
462 // EDX: function name. 465 // EDX: ic-data array.
463 // ECX: raw_null. 466 // ECX: raw_null.
464 // EDI: arguments descriptor array. 467 // EDI: arguments descriptor array.
465 // The target function was not found. 468 // The target function was not found.
466 // First check to see if this is a getter function and we are 469 // First check to see if this is a getter function and we are
467 // trying to create a closure of an instance function. 470 // trying to create a closure of an instance function.
468 // Push values that need to be preserved across runtime call. 471 // Push values that need to be preserved across runtime call.
469 __ pushl(EAX); // Preserve receiver. 472 __ pushl(EAX); // Preserve receiver.
470 __ pushl(EDX); // Preserve function name. 473 __ pushl(EDX); // Preserve ic-data array.
471 __ pushl(EDI); // Preserve arguments descriptor array. 474 __ pushl(EDI); // Preserve arguments descriptor array.
472 475
473 __ pushl(Immediate(0)); 476 __ pushl(Immediate(0));
474 __ pushl(EAX); // Push receiver. 477 __ pushl(EAX); // Push receiver.
475 __ pushl(EDX); // Function name. 478 __ pushl(EDX); // Ic-data array.
476 __ CallRuntimeFromStub(kResolveImplicitClosureFunctionRuntimeEntry); 479 __ CallRuntimeFromStub(kResolveImplicitClosureFunctionRuntimeEntry);
477 __ popl(EAX); 480 __ popl(EAX);
478 __ popl(EAX); 481 __ popl(EAX);
479 __ popl(ECX); // Get return value into ECX, might be Closure object. 482 __ popl(ECX); // Get return value into ECX, might be Closure object.
480 483
481 // Pop preserved values. 484 // Pop preserved values.
482 __ popl(EDI); // Restore arguments descriptor array. 485 __ popl(EDI); // Restore arguments descriptor array.
483 __ popl(EDX); // Restore function name. 486 __ popl(EDX); // Restore ic-data array.
484 __ popl(EAX); // Restore receiver. 487 __ popl(EAX); // Restore receiver.
485 488
486 __ cmpl(ECX, raw_null); 489 __ cmpl(ECX, raw_null);
487 Label check_implicit_closure_through_getter; 490 Label check_implicit_closure_through_getter;
488 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump); 491 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump);
489 492
490 __ movl(EAX, ECX); // Return value is the closure object. 493 __ movl(EAX, ECX); // Return value is the closure object.
491 // Remove the stub frame as we are about return. 494 // Remove the stub frame as we are about return.
492 __ LeaveFrame(); 495 __ LeaveFrame();
493 __ ret(); 496 __ ret();
494 497
495 __ Bind(&check_implicit_closure_through_getter); 498 __ Bind(&check_implicit_closure_through_getter);
496 // EAX: receiver. 499 // EAX: receiver.
497 // EDX: function name. 500 // EDX: ic-data array.
498 // ECX: raw_null. 501 // ECX: raw_null.
499 // EDI: arguments descriptor array. 502 // EDI: arguments descriptor array.
500 // This is not the case of an instance so invoke the getter of the 503 // This is not the case of an instance so invoke the getter of the
501 // same name and see if we get a closure back which we are then 504 // same name and see if we get a closure back which we are then
502 // supposed to invoke. 505 // supposed to invoke.
503 // Push values that need to be preserved across runtime call. 506 // Push values that need to be preserved across runtime call.
504 __ pushl(EAX); // Preserve receiver. 507 __ pushl(EAX); // Preserve receiver.
505 __ pushl(EDX); // Preserve function name. 508 __ pushl(EDX); // Preserve ic-data array.
506 __ pushl(EDI); // Preserve arguments descriptor array. 509 __ pushl(EDI); // Preserve arguments descriptor array.
507 510
508 __ pushl(Immediate(0)); 511 __ pushl(Immediate(0));
509 __ pushl(EAX); // Push receiver. 512 __ pushl(EAX); // Push receiver.
510 __ pushl(EDX); // Function name. 513 __ pushl(EDX); // Ic-data array.
511 __ CallRuntimeFromStub(kResolveImplicitClosureThroughGetterRuntimeEntry); 514 __ CallRuntimeFromStub(kResolveImplicitClosureThroughGetterRuntimeEntry);
512 __ popl(EDX); // Restore function name. 515 __ popl(EDX); // Pop argument.
513 __ popl(EAX); // Restore receiver. 516 __ popl(EAX); // Pop argument.
514 __ popl(ECX); // get return value into ECX, might be Closure object. 517 __ popl(ECX); // get return value into ECX, might be Closure object.
515 518
516 // Pop preserved values. 519 // Pop preserved values.
517 __ popl(EDI); // Restore arguments descriptor array. 520 __ popl(EDI); // Restore arguments descriptor array.
518 __ popl(EDX); // Restore function name. 521 __ popl(EDX); // Restore ic-data array.
519 __ popl(EAX); // Restore receiver. 522 __ popl(EAX); // Restore receiver.
520 523
521 __ cmpl(ECX, raw_null); 524 __ cmpl(ECX, raw_null);
522 Label function_not_found; 525 Label function_not_found;
523 __ j(EQUAL, &function_not_found, Assembler::kNearJump); 526 __ j(EQUAL, &function_not_found, Assembler::kNearJump);
524 527
525 // ECX: Closure object. 528 // ECX: Closure object.
526 // EDI: Arguments descriptor array. 529 // EDI: Arguments descriptor array.
527 __ pushl(Immediate(0)); // Result from invoking Closure. 530 __ pushl(Immediate(0)); // Result from invoking Closure.
528 __ pushl(ECX); // Closure object. 531 __ pushl(ECX); // Closure object.
(...skipping 20 matching lines...) Expand all
549 __ popl(EAX); // Get result into EAX. 552 __ popl(EAX); // Get result into EAX.
550 553
551 // Remove the stub frame as we are about to return. 554 // Remove the stub frame as we are about to return.
552 __ LeaveFrame(); 555 __ LeaveFrame();
553 __ ret(); 556 __ ret();
554 557
555 __ Bind(&function_not_found); 558 __ Bind(&function_not_found);
556 // The target function was not found, so invoke method 559 // The target function was not found, so invoke method
557 // "void noSuchMethod(function_name, args_array)". 560 // "void noSuchMethod(function_name, args_array)".
558 // EAX: receiver. 561 // EAX: receiver.
559 // EDX: function name. 562 // EDX: ic-data array.
560 // ECX: raw_null. 563 // ECX: raw_null.
561 // EDI: argument descriptor array. 564 // EDI: argument descriptor array.
562 565
563 // Setup space for return value on stack by pushing smi 0. 566 // Setup space for return value on stack by pushing smi 0.
564 __ pushl(Immediate(0)); // Result from noSuchMethod. 567 __ pushl(Immediate(0)); // Result from noSuchMethod.
565 __ pushl(EAX); // Receiver. 568 __ pushl(EAX); // Receiver.
566 __ pushl(EDX); // Function name. 569 __ pushl(EDX); // IC-data array.
567 __ pushl(EDI); // Argument descriptor array. 570 __ pushl(EDI); // Argument descriptor array.
568 __ movl(EDI, FieldAddress(EDI, Array::data_offset())); 571 __ movl(EDI, FieldAddress(EDI, Array::data_offset()));
569 __ SmiUntag(EDI); 572 __ SmiUntag(EDI);
570 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. 573 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver.
571 // See stack layout below explaining "wordSize * 6" offset. 574 // See stack layout below explaining "wordSize * 6" offset.
572 PushArgumentsArray(assembler, (kWordSize * 6)); 575 PushArgumentsArray(assembler, (kWordSize * 6));
573 576
574 // Stack: 577 // Stack:
575 // TOS + 0: Argument array. 578 // TOS + 0: Argument array.
576 // TOS + 1: Argument descriptor array. 579 // TOS + 1: Argument descriptor array.
577 // TOS + 2: Function name. 580 // TOS + 2: IC-data array.
578 // TOS + 3: Receiver. 581 // TOS + 3: Receiver.
579 // TOS + 4: Place for result from noSuchMethod. 582 // TOS + 4: Place for result from noSuchMethod.
580 // TOS + 5: Saved EBP of previous frame. <== EBP 583 // TOS + 5: Saved EBP of previous frame. <== EBP
581 // TOS + 6: Dart code return address 584 // TOS + 6: Dart code return address
582 // TOS + 7: Last argument of caller. 585 // TOS + 7: Last argument of caller.
583 // .... 586 // ....
584 587
585 __ CallRuntimeFromStub(kInvokeNoSuchMethodFunctionRuntimeEntry); 588 __ CallRuntimeFromStub(kInvokeNoSuchMethodFunctionRuntimeEntry);
586 // Remove arguments. 589 // Remove arguments.
587 __ popl(EAX); 590 __ popl(EAX);
(...skipping 12 matching lines...) Expand all
600 __ EnterFrame(0); 603 __ EnterFrame(0);
601 // Stack at this point: 604 // Stack at this point:
602 // TOS + 0: Saved EBP of previous frame. <== EBP 605 // TOS + 0: Saved EBP of previous frame. <== EBP
603 // TOS + 1: Dart code return address 606 // TOS + 1: Dart code return address
604 // TOS + 2: Last argument of caller. 607 // TOS + 2: Last argument of caller.
605 // .... 608 // ....
606 // Total number of args is the first Smi in args descriptor array (EDX). 609 // Total number of args is the first Smi in args descriptor array (EDX).
607 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); // EAX is a Smi. 610 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); // EAX is a Smi.
608 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); // Load receiver. 611 __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize)); // Load receiver.
609 __ pushl(EDX); // Preserve arguments descriptor array. 612 __ pushl(EDX); // Preserve arguments descriptor array.
610 __ pushl(ECX); // Preserve function name. 613 __ pushl(ECX); // Preserve ic-data array.
611 __ pushl(EAX); // Push receiver. 614 __ pushl(EAX); // Push receiver.
612 __ CallRuntimeFromStub(kResolvePatchInstanceCallRuntimeEntry); 615 __ CallRuntimeFromStub(kResolvePatchInstanceCallRuntimeEntry);
613 __ popl(EAX); // Remove receiver pushed earlier. 616 __ popl(EAX); // Remove receiver pushed earlier.
614 // Pop preserved values 617 // Pop preserved values
615 __ popl(ECX); // Restore function name. 618 __ popl(ECX); // Restore ic-data array.
616 __ popl(EDX); // Restore arguments descriptor array. 619 __ popl(EDX); // Restore arguments descriptor array.
617 __ LeaveFrame(); 620 __ LeaveFrame();
618 __ popl(EAX); 621 __ popl(EAX);
619 // Reexecute call. 622 // Reexecute call.
620 __ subl(EAX, Immediate(Assembler::kCallExternalLabelSize)); 623 __ subl(EAX, Immediate(Assembler::kCallExternalLabelSize));
621 __ jmp(EAX); 624 __ jmp(EAX);
622 } 625 }
623 626
624 627
625 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 628 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 } 1392 }
1390 1393
1391 1394
1392 // Called for invoking noSuchMethod function from the entry code of a dart 1395 // Called for invoking noSuchMethod function from the entry code of a dart
1393 // function after an error in passed named arguments is detected. 1396 // function after an error in passed named arguments is detected.
1394 // Input parameters: 1397 // Input parameters:
1395 // EBP : points to previous frame pointer. 1398 // EBP : points to previous frame pointer.
1396 // EBP + 4 : points to return address. 1399 // EBP + 4 : points to return address.
1397 // EBP + 8 : address of last argument (arg n-1). 1400 // EBP + 8 : address of last argument (arg n-1).
1398 // EBP + 8 + 4*(n-1) : address of first argument (arg 0). 1401 // EBP + 8 + 4*(n-1) : address of first argument (arg 0).
1399 // ECX : function name. 1402 // ECX : ic-data array.
1400 // EDX : arguments descriptor array. 1403 // EDX : arguments descriptor array.
1401 // Uses EAX, EBX, EDI as temporary registers. 1404 // Uses EAX, EBX, EDI as temporary registers.
1402 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1405 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1403 // The target function was not found, so invoke method 1406 // The target function was not found, so invoke method
1404 // "void noSuchMethod(function_name, Array arguments)". 1407 // "void noSuchMethod(function_name, Array arguments)".
1405 // TODO(regis): For now, we simply pass the actual arguments, both positional 1408 // TODO(regis): For now, we simply pass the actual arguments, both positional
1406 // and named, as the argument array. This is not correct if out-of-order 1409 // and named, as the argument array. This is not correct if out-of-order
1407 // named arguments were passed. 1410 // named arguments were passed.
1408 // The signature of the "noSuchMethod" method has to change from 1411 // The signature of the "noSuchMethod" method has to change from
1409 // noSuchMethod(String name, Array arguments) to something like 1412 // noSuchMethod(String name, Array arguments) to something like
1410 // noSuchMethod(InvocationMirror call). 1413 // noSuchMethod(InvocationMirror call).
1411 // Also, the class NoSuchMethodException has to be modified accordingly. 1414 // Also, the class NoSuchMethodException has to be modified accordingly.
1412 // Total number of args is the first Smi in args descriptor array (EDX). 1415 // Total number of args is the first Smi in args descriptor array (EDX).
1413 __ movl(EDI, FieldAddress(EDX, Array::data_offset())); 1416 __ movl(EDI, FieldAddress(EDX, Array::data_offset()));
1414 __ SmiUntag(EDI); 1417 __ SmiUntag(EDI);
1415 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. 1418 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver.
1416 1419
1417 __ EnterFrame(0); 1420 __ EnterFrame(0);
1418 // Setup space for return value on stack by pushing smi 0. 1421 // Setup space for return value on stack by pushing smi 0.
1419 __ pushl(Immediate(0)); // Result from noSuchMethod. 1422 __ pushl(Immediate(0)); // Result from noSuchMethod.
1420 __ pushl(EAX); // Receiver. 1423 __ pushl(EAX); // Receiver.
1421 __ pushl(ECX); // Function name. 1424 __ pushl(ECX); // IC data array.
1422 __ pushl(EDX); // Arguments descriptor array. 1425 __ pushl(EDX); // Arguments descriptor array.
1423 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. 1426 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver.
1424 // See stack layout below explaining "wordSize * 8" offset. 1427 // See stack layout below explaining "wordSize * 8" offset.
1425 PushArgumentsArray(assembler, (kWordSize * 8)); 1428 PushArgumentsArray(assembler, (kWordSize * 8));
1426 1429
1427 // Stack: 1430 // Stack:
1428 // TOS + 0: Argument array. 1431 // TOS + 0: Argument array.
1429 // TOS + 1: Arguments descriptor array. 1432 // TOS + 1: Arguments descriptor array.
1430 // TOS + 2: Function name. 1433 // TOS + 2: Ic-data array.
1431 // TOS + 3: Receiver. 1434 // TOS + 3: Receiver.
1432 // TOS + 4: Place for result from noSuchMethod. 1435 // TOS + 4: Place for result from noSuchMethod.
1433 // TOS + 5: Saved EBP of previous frame. <== EBP 1436 // TOS + 5: Saved EBP of previous frame. <== EBP
1434 // TOS + 6: Dart callee (or stub) code return address 1437 // TOS + 6: Dart callee (or stub) code return address
1435 // TOS + 7: Saved EBP of dart caller frame. 1438 // TOS + 7: Saved EBP of dart caller frame.
1436 // TOS + 8: Dart caller code return address 1439 // TOS + 8: Dart caller code return address
1437 // TOS + 9: Last argument of caller. 1440 // TOS + 9: Last argument of caller.
1438 // .... 1441 // ....
1439 __ CallRuntimeFromStub(kInvokeNoSuchMethodFunctionRuntimeEntry); 1442 __ CallRuntimeFromStub(kInvokeNoSuchMethodFunctionRuntimeEntry);
1440 // Remove arguments. 1443 // Remove arguments.
1441 __ popl(EAX); 1444 __ popl(EAX);
1442 __ popl(EAX); 1445 __ popl(EAX);
1443 __ popl(EAX); 1446 __ popl(EAX);
1444 __ popl(EAX); 1447 __ popl(EAX);
1445 __ popl(EAX); // Get result into EAX. 1448 __ popl(EAX); // Get result into EAX.
1446 1449
1447 // Remove the stub frame as we are about to return. 1450 // Remove the stub frame as we are about to return.
1448 __ LeaveFrame(); 1451 __ LeaveFrame();
1449 __ ret(); 1452 __ ret();
1450 } 1453 }
1451 1454
1452 } // namespace dart 1455 } // namespace dart
1453 1456
1454 #endif // defined TARGET_ARCH_IA32 1457 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/ic_stubs_ia32_test.cc ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698