| OLD | NEW |
| 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/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1551 // - Check if 'num_args' (including receiver) match any IC data group. | 1551 // - Check if 'num_args' (including receiver) match any IC data group. |
| 1552 // - Match found -> jump to target. | 1552 // - Match found -> jump to target. |
| 1553 // - Match not found -> jump to IC miss. | 1553 // - Match not found -> jump to IC miss. |
| 1554 // TODO(srdjan): Change IC data to keep class ids as integers not as Smi-s. | 1554 // TODO(srdjan): Change IC data to keep class ids as integers not as Smi-s. |
| 1555 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, | 1555 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, |
| 1556 intptr_t num_args) { | 1556 intptr_t num_args) { |
| 1557 const Immediate raw_null = | 1557 const Immediate raw_null = |
| 1558 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1558 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1559 | 1559 |
| 1560 __ movl(EBX, FieldAddress(ECX, ICData::function_offset())); | 1560 __ movl(EBX, FieldAddress(ECX, ICData::function_offset())); |
| 1561 Label is_hot; |
| 1562 if (FlowGraphCompiler::CanOptimize()) { |
| 1563 ASSERT(FLAG_optimization_counter_threshold > 1); |
| 1564 // The usage_counter is always less than FLAG_optimization_counter_threshold |
| 1565 // except when the function gets optimized. |
| 1566 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()), |
| 1567 Immediate(FLAG_optimization_counter_threshold - 1)); |
| 1568 // Do not increment to equality with threshold, since a counter greater |
| 1569 // than threshold denotes a function that was already optimized. |
| 1570 // The equality should be reached only at exit of the method |
| 1571 // (return instruction). |
| 1572 __ j(EQUAL, &is_hot, Assembler::kNearJump); |
| 1573 // As long as VM has no OSR do not optimize in the middle of the function |
| 1574 // but only at exit so that we have collected all type feedback before |
| 1575 // optimizing. |
| 1576 } |
| 1561 __ incl(FieldAddress(EBX, Function::usage_counter_offset())); | 1577 __ incl(FieldAddress(EBX, Function::usage_counter_offset())); |
| 1562 if (FlowGraphCompiler::CanOptimize()) { | 1578 __ Bind(&is_hot); |
| 1563 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()), | |
| 1564 Immediate(FLAG_optimization_counter_threshold)); | |
| 1565 Label not_yet_hot, already_optimized; | |
| 1566 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); | |
| 1567 __ j(GREATER, &already_optimized, Assembler::kNearJump); | |
| 1568 // Create a stub frame as we are pushing some objects on the stack before | |
| 1569 // calling into the runtime. | |
| 1570 AssemblerMacros::EnterStubFrame(assembler); | |
| 1571 __ pushl(ECX); // Preserve inline cache data object. | |
| 1572 __ pushl(EDX); // Preserve arguments array. | |
| 1573 __ pushl(EBX); // Argument for runtime: function object. | |
| 1574 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | |
| 1575 __ popl(EBX); // Remove argument. | |
| 1576 __ popl(EDX); // Restore arguments array. | |
| 1577 __ popl(ECX); // Restore inline cache data object. | |
| 1578 __ LeaveFrame(); | |
| 1579 __ Bind(¬_yet_hot); | |
| 1580 __ Bind(&already_optimized); | |
| 1581 } | |
| 1582 | 1579 |
| 1583 ASSERT(num_args > 0); | 1580 ASSERT(num_args > 0); |
| 1584 // Get receiver (first read number of arguments from argument descriptor array | 1581 // Get receiver (first read number of arguments from argument descriptor array |
| 1585 // and then access the receiver from the stack). | 1582 // and then access the receiver from the stack). |
| 1586 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1583 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
| 1587 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi. | 1584 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi. |
| 1588 | 1585 |
| 1589 Label get_class_id_as_smi, ic_miss; | 1586 Label get_class_id_as_smi, ic_miss; |
| 1590 // ECX: IC data array. | 1587 // ECX: IC data array. |
| 1591 | 1588 |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 __ movl(EAX, Address(ESP, 4 * kWordSize)); // Load error object. | 1945 __ movl(EAX, Address(ESP, 4 * kWordSize)); // Load error object. |
| 1949 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. | 1946 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. |
| 1950 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. | 1947 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. |
| 1951 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. | 1948 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. |
| 1952 __ jmp(EBX); // Jump to the exception handler code. | 1949 __ jmp(EBX); // Jump to the exception handler code. |
| 1953 } | 1950 } |
| 1954 | 1951 |
| 1955 } // namespace dart | 1952 } // namespace dart |
| 1956 | 1953 |
| 1957 #endif // defined TARGET_ARCH_IA32 | 1954 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |