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

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

Issue 1191813002: Port "Add flag to disable lazy compilation of invocation dispatchers." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
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 11 matching lines...) Expand all
22 #define __ assembler-> 22 #define __ assembler->
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); 26 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
27 DEFINE_FLAG(bool, use_slow_path, false, 27 DEFINE_FLAG(bool, use_slow_path, false,
28 "Set to true for debugging & verifying the slow paths."); 28 "Set to true for debugging & verifying the slow paths.");
29 DECLARE_FLAG(bool, trace_optimized_ic_calls); 29 DECLARE_FLAG(bool, trace_optimized_ic_calls);
30 DECLARE_FLAG(int, optimization_counter_threshold); 30 DECLARE_FLAG(int, optimization_counter_threshold);
31 DECLARE_FLAG(bool, support_debugger); 31 DECLARE_FLAG(bool, support_debugger);
32 DECLARE_FLAG(bool, lazy_dispatchers);
32 33
33 #define INT32_SIZEOF(x) static_cast<int32_t>(sizeof(x)) 34 #define INT32_SIZEOF(x) static_cast<int32_t>(sizeof(x))
34 35
35 // Input parameters: 36 // Input parameters:
36 // ESP : points to return address. 37 // ESP : points to return address.
37 // ESP + 4 : address of last argument in argument array. 38 // ESP + 4 : address of last argument in argument array.
38 // ESP + 4*EDX : address of first argument in argument array. 39 // ESP + 4*EDX : address of first argument in argument array.
39 // ESP + 4*EDX + 4 : address of return value. 40 // ESP + 4*EDX + 4 : address of return value.
40 // ECX : address of the runtime function to call. 41 // ECX : address of the runtime function to call.
41 // EDX : number of arguments to the call. 42 // EDX : number of arguments to the call.
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 __ pushl(EBX); 499 __ pushl(EBX);
499 GenerateDeoptimizationSequence(assembler, true); // Preserve EAX. 500 GenerateDeoptimizationSequence(assembler, true); // Preserve EAX.
500 } 501 }
501 502
502 503
503 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 504 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
504 GenerateDeoptimizationSequence(assembler, false); // Don't preserve EAX. 505 GenerateDeoptimizationSequence(assembler, false); // Don't preserve EAX.
505 } 506 }
506 507
507 508
509 static void GenerateDispatcherCode(Assembler* assembler,
510 Label* call_target_function) {
511 __ Comment("NoSuchMethodDispatch");
512 // When lazily generated invocation dispatchers are disabled, the
513 // miss-handler may return null.
514 const Immediate& raw_null =
515 Immediate(reinterpret_cast<intptr_t>(Object::null()));
516 __ cmpl(EAX, raw_null);
517 __ j(NOT_EQUAL, call_target_function);
518 __ EnterStubFrame();
519 // Load the receiver.
520 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
521 __ movl(EAX, Address(
522 EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
523 __ pushl(raw_null); // Setup space on stack for result.
524 __ pushl(EAX); // Receiver.
525 __ pushl(ECX);
526 __ pushl(EDX); // Arguments descriptor array.
527 __ movl(EDX, EDI);
528 // EDX: Smi-tagged arguments array length.
529 PushArgumentsArray(assembler);
530 const intptr_t kNumArgs = 4;
531 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
532 __ popl(EAX);
Florian Schneider 2015/06/17 08:01:34 __ Drop(4); __ popl(EAX);
rmacnak 2015/06/17 17:42:20 Done.
533 __ popl(EAX);
534 __ popl(EAX);
535 __ popl(EAX);
536 __ popl(EAX); // Return value.
537 __ LeaveFrame();
538 __ ret();
539 }
540
541
508 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 542 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
509 __ EnterStubFrame(); 543 __ EnterStubFrame();
510 // Load the receiver into EAX. The argument count in the arguments 544 // Load the receiver into EAX. The argument count in the arguments
511 // descriptor in EDX is a smi. 545 // descriptor in EDX is a smi.
512 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 546 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
513 // Two words (saved fp, stub's pc marker) in the stack above the return 547 // Two words (saved fp, stub's pc marker) in the stack above the return
514 // address. 548 // address.
515 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize)); 549 __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize));
516 // Preserve IC data and arguments descriptor. 550 // Preserve IC data and arguments descriptor.
517 __ pushl(ECX); 551 __ pushl(ECX);
518 __ pushl(EDX); 552 __ pushl(EDX);
519 553
520 const Immediate& raw_null = 554 const Immediate& raw_null =
521 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); 555 Immediate(reinterpret_cast<intptr_t>(Instructions::null()));
522 __ pushl(raw_null); // Space for the result of the runtime call. 556 __ pushl(raw_null); // Space for the result of the runtime call.
523 __ pushl(EAX); // Pass receiver. 557 __ pushl(EAX); // Pass receiver.
524 __ pushl(ECX); // Pass IC data. 558 __ pushl(ECX); // Pass IC data.
525 __ pushl(EDX); // Pass arguments descriptor. 559 __ pushl(EDX); // Pass arguments descriptor.
526 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); 560 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
527 // Discard arguments. 561 // Discard arguments.
528 __ popl(EAX); 562 __ popl(EAX);
529 __ popl(EAX); 563 __ popl(EAX);
530 __ popl(EAX); 564 __ popl(EAX);
531 __ popl(EAX); // Return value from the runtime call (function). 565 __ popl(EAX); // Return value from the runtime call (function).
532 __ popl(EDX); // Restore arguments descriptor. 566 __ popl(EDX); // Restore arguments descriptor.
533 __ popl(ECX); // Restore IC data. 567 __ popl(ECX); // Restore IC data.
534 __ LeaveFrame(); 568 __ LeaveFrame();
535 569
570 if (!FLAG_lazy_dispatchers) {
571 Label call_target_function;
572 GenerateDispatcherCode(assembler, &call_target_function);
573 __ Bind(&call_target_function);
574 }
575
536 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); 576 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
537 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 577 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
538 __ jmp(EBX); 578 __ jmp(EBX);
539 } 579 }
540 580
541 581
542 // Called for inline allocation of arrays. 582 // Called for inline allocation of arrays.
543 // Input parameters: 583 // Input parameters:
544 // EDX : Array length as Smi (must be preserved). 584 // EDX : Array length as Smi (must be preserved).
545 // ECX : array element type (either NULL or an instantiated type). 585 // ECX : array element type (either NULL or an instantiated type).
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 1403
1364 // EAX: next argument class ID (smi). 1404 // EAX: next argument class ID (smi).
1365 __ movl(EDI, Address(EBX, i * kWordSize)); 1405 __ movl(EDI, Address(EBX, i * kWordSize));
1366 // EDI: next class ID to check (smi). 1406 // EDI: next class ID to check (smi).
1367 } 1407 }
1368 __ cmpl(EAX, EDI); // Class id match? 1408 __ cmpl(EAX, EDI); // Class id match?
1369 if (i < (num_args - 1)) { 1409 if (i < (num_args - 1)) {
1370 __ j(NOT_EQUAL, &update); // Continue. 1410 __ j(NOT_EQUAL, &update); // Continue.
1371 } else { 1411 } else {
1372 // Last check, all checks before matched. 1412 // Last check, all checks before matched.
1373 __ j(EQUAL, &found, Assembler::kNearJump); // Break. 1413 __ j(EQUAL, &found); // Break.
1374 } 1414 }
1375 } 1415 }
1376 __ Bind(&update); 1416 __ Bind(&update);
1377 // Reload receiver class ID. It has not been destroyed when num_args == 1. 1417 // Reload receiver class ID. It has not been destroyed when num_args == 1.
1378 if (num_args > 1) { 1418 if (num_args > 1) {
1379 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1419 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1380 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); 1420 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0));
1381 __ LoadTaggedClassIdMayBeSmi(EAX, EDI); 1421 __ LoadTaggedClassIdMayBeSmi(EAX, EDI);
1382 } 1422 }
1383 1423
(...skipping 27 matching lines...) Expand all
1411 __ CallRuntime(handle_ic_miss, num_args + 1); 1451 __ CallRuntime(handle_ic_miss, num_args + 1);
1412 // Remove the call arguments pushed earlier, including the IC data object. 1452 // Remove the call arguments pushed earlier, including the IC data object.
1413 for (intptr_t i = 0; i < num_args + 1; i++) { 1453 for (intptr_t i = 0; i < num_args + 1; i++) {
1414 __ popl(EAX); 1454 __ popl(EAX);
1415 } 1455 }
1416 __ popl(EAX); // Pop returned function object into EAX. 1456 __ popl(EAX); // Pop returned function object into EAX.
1417 __ popl(ECX); // Restore IC data array. 1457 __ popl(ECX); // Restore IC data array.
1418 __ popl(EDX); // Restore arguments descriptor array. 1458 __ popl(EDX); // Restore arguments descriptor array.
1419 __ LeaveFrame(); 1459 __ LeaveFrame();
1420 Label call_target_function; 1460 Label call_target_function;
1421 __ jmp(&call_target_function); 1461 if (!FLAG_lazy_dispatchers) {
1462 GenerateDispatcherCode(assembler, &call_target_function);
1463 } else {
1464 __ jmp(&call_target_function);
1465 }
1422 1466
1423 __ Bind(&found); 1467 __ Bind(&found);
1424 1468
1425 // EBX: Pointer to an IC data check group. 1469 // EBX: Pointer to an IC data check group.
1426 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1470 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1427 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1471 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1428 if (FLAG_optimization_counter_threshold >= 0) { 1472 if (FLAG_optimization_counter_threshold >= 0) {
1429 __ Comment("Update caller's counter"); 1473 __ Comment("Update caller's counter");
1430 __ movl(EAX, Address(EBX, count_offset)); 1474 __ movl(EAX, Address(EBX, count_offset));
1431 __ addl(EAX, Immediate(Smi::RawValue(1))); 1475 __ addl(EAX, Immediate(Smi::RawValue(1)));
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 // EBX: entry point. 2126 // EBX: entry point.
2083 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2127 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2084 EmitMegamorphicLookup(assembler, EDI, EBX, EBX); 2128 EmitMegamorphicLookup(assembler, EDI, EBX, EBX);
2085 __ ret(); 2129 __ ret();
2086 } 2130 }
2087 2131
2088 2132
2089 } // namespace dart 2133 } // namespace dart
2090 2134
2091 #endif // defined TARGET_ARCH_IA32 2135 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698