Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |