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

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

Issue 221173011: Simplify handling of IC and megamorphic cache misses. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 6 years, 8 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 __ movl(EAX, Address(EBX, 0)); 389 __ movl(EAX, Address(EBX, 0));
390 __ movl(Address(ECX, 0), EAX); 390 __ movl(Address(ECX, 0), EAX);
391 __ AddImmediate(ECX, Immediate(kWordSize)); 391 __ AddImmediate(ECX, Immediate(kWordSize));
392 __ AddImmediate(EBX, Immediate(-kWordSize)); 392 __ AddImmediate(EBX, Immediate(-kWordSize));
393 __ Bind(&loop_condition); 393 __ Bind(&loop_condition);
394 __ decl(EDX); 394 __ decl(EDX);
395 __ j(POSITIVE, &loop, Assembler::kNearJump); 395 __ j(POSITIVE, &loop, Assembler::kNearJump);
396 } 396 }
397 397
398 398
399 // Input parameters:
400 // ECX: ic-data.
401 // EDX: arguments descriptor array.
402 // Note: The receiver object is the first argument to the function being
403 // called, the stub accesses the receiver from this location directly
404 // when trying to resolve the call.
405 // Uses EDI.
406 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
407 __ EnterStubFrame();
408
409 const Immediate& raw_null =
410 Immediate(reinterpret_cast<intptr_t>(Object::null()));
411 __ pushl(raw_null); // Space for the return value.
412
413 // Push the receiver as an argument. Load the smi-tagged argument
414 // count into EDI to index the receiver in the stack. There are
415 // three words (null, stub's pc marker, saved fp) above the return
416 // address.
417 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
418 __ pushl(Address(ESP, EDI, TIMES_2, (3 * kWordSize)));
419
420 __ pushl(ECX); // Pass IC data object.
421 __ pushl(EDX); // Pass arguments descriptor array.
422
423 // Pass the call's arguments array.
424 __ movl(EDX, EDI); // Smi-tagged arguments array length.
425 PushArgumentsArray(assembler);
426
427 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4);
428
429 // Remove arguments.
430 __ Drop(4);
431 __ popl(EAX); // Get result into EAX.
432 __ LeaveFrame();
433 __ ret();
434 }
435
436
437 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 399 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
438 intptr_t deopt_reason, 400 intptr_t deopt_reason,
439 uword saved_registers_address); 401 uword saved_registers_address);
440 402
441 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); 403 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
442 404
443 405
444 // Used by eager and lazy deoptimization. Preserve result in EAX if necessary. 406 // Used by eager and lazy deoptimization. Preserve result in EAX if necessary.
445 // This stub translates optimized frame into unoptimized frame. The optimized 407 // This stub translates optimized frame into unoptimized frame. The optimized
446 // frame can contain values in registers and on stack, the unoptimized 408 // frame can contain values in registers and on stack, the unoptimized
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); 538 Immediate(reinterpret_cast<intptr_t>(Instructions::null()));
577 __ pushl(raw_null); // Space for the result of the runtime call. 539 __ pushl(raw_null); // Space for the result of the runtime call.
578 __ pushl(EAX); // Pass receiver. 540 __ pushl(EAX); // Pass receiver.
579 __ pushl(ECX); // Pass IC data. 541 __ pushl(ECX); // Pass IC data.
580 __ pushl(EDX); // Pass arguments descriptor. 542 __ pushl(EDX); // Pass arguments descriptor.
581 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); 543 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
582 // Discard arguments. 544 // Discard arguments.
583 __ popl(EAX); 545 __ popl(EAX);
584 __ popl(EAX); 546 __ popl(EAX);
585 __ popl(EAX); 547 __ popl(EAX);
586 __ popl(EAX); // Return value from the runtime call (instructions). 548 __ popl(EAX); // Return value from the runtime call (function).
587 __ popl(EDX); // Restore arguments descriptor. 549 __ popl(EDX); // Restore arguments descriptor.
588 __ popl(ECX); // Restore IC data. 550 __ popl(ECX); // Restore IC data.
589 __ LeaveFrame(); 551 __ LeaveFrame();
590 552
591 Label lookup; 553 __ movl(EBX, FieldAddress(EAX, Function::code_offset()));
592 __ cmpl(EAX, raw_null); 554 __ movl(EBX, FieldAddress(EBX, Code::instructions_offset()));
593 __ j(EQUAL, &lookup, Assembler::kNearJump); 555 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
594 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 556 __ jmp(EBX);
595 __ jmp(EAX);
596
597 __ Bind(&lookup);
598 __ jmp(&StubCode::InstanceFunctionLookupLabel());
599 } 557 }
600 558
601 559
602 // Called for inline allocation of arrays. 560 // Called for inline allocation of arrays.
603 // Input parameters: 561 // Input parameters:
604 // EDX : Array length as Smi. 562 // EDX : Array length as Smi.
605 // ECX : array element type (either NULL or an instantiated type). 563 // ECX : array element type (either NULL or an instantiated type).
606 // Uses EAX, EBX, ECX, EDI as temporary registers. 564 // Uses EAX, EBX, ECX, EDI as temporary registers.
607 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved. 565 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved.
608 // The newly allocated object is returned in EAX. 566 // The newly allocated object is returned in EAX.
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 for (intptr_t i = 0; i < num_args; i++) { 1413 for (intptr_t i = 0; i < num_args; i++) {
1456 __ movl(EBX, Address(EAX, -kWordSize * i)); 1414 __ movl(EBX, Address(EAX, -kWordSize * i));
1457 __ pushl(EBX); 1415 __ pushl(EBX);
1458 } 1416 }
1459 __ pushl(ECX); // Pass IC data object. 1417 __ pushl(ECX); // Pass IC data object.
1460 __ CallRuntime(handle_ic_miss, num_args + 1); 1418 __ CallRuntime(handle_ic_miss, num_args + 1);
1461 // Remove the call arguments pushed earlier, including the IC data object. 1419 // Remove the call arguments pushed earlier, including the IC data object.
1462 for (intptr_t i = 0; i < num_args + 1; i++) { 1420 for (intptr_t i = 0; i < num_args + 1; i++) {
1463 __ popl(EAX); 1421 __ popl(EAX);
1464 } 1422 }
1465 __ popl(EAX); // Pop returned code object into EAX (null if not found). 1423 __ popl(EAX); // Pop returned function object into EAX.
1466 __ popl(ECX); // Restore IC data array. 1424 __ popl(ECX); // Restore IC data array.
1467 __ popl(EDX); // Restore arguments descriptor array. 1425 __ popl(EDX); // Restore arguments descriptor array.
1468 __ LeaveFrame(); 1426 __ LeaveFrame();
1469 Label call_target_function; 1427 Label call_target_function;
1470 __ cmpl(EAX, raw_null); 1428 __ jmp(&call_target_function);
1471 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
1472 // NoSuchMethod or closure.
1473 // Mark IC call that it may be a closure call that does not collect
1474 // type feedback.
1475 __ movb(FieldAddress(ECX, ICData::is_closure_call_offset()), Immediate(1));
1476 __ jmp(&StubCode::InstanceFunctionLookupLabel());
1477 1429
1478 __ Bind(&found); 1430 __ Bind(&found);
1479 // EBX: Pointer to an IC data check group. 1431 // EBX: Pointer to an IC data check group.
1480 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1432 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1481 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1433 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1482 __ movl(EAX, Address(EBX, target_offset)); 1434 __ movl(EAX, Address(EBX, target_offset));
1483 __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1))); 1435 __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
1484 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); 1436 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump);
1485 __ movl(Address(EBX, count_offset), 1437 __ movl(Address(EBX, count_offset),
1486 Immediate(Smi::RawValue(Smi::kMaxValue))); 1438 Immediate(Smi::RawValue(Smi::kMaxValue)));
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 const Register temp = ECX; 1938 const Register temp = ECX;
1987 __ movl(left, Address(ESP, 2 * kWordSize)); 1939 __ movl(left, Address(ESP, 2 * kWordSize));
1988 __ movl(right, Address(ESP, 1 * kWordSize)); 1940 __ movl(right, Address(ESP, 1 * kWordSize));
1989 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1941 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1990 __ ret(); 1942 __ ret();
1991 } 1943 }
1992 1944
1993 } // namespace dart 1945 } // namespace dart
1994 1946
1995 #endif // defined TARGET_ARCH_IA32 1947 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698