| 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 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 | 2022 |
| 2023 | 2023 |
| 2024 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { | 2024 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { |
| 2025 __ LoadTaggedClassIdMayBeSmi(EAX, EBX); | 2025 __ LoadTaggedClassIdMayBeSmi(EAX, EBX); |
| 2026 // EAX: class ID of the receiver (smi). | 2026 // EAX: class ID of the receiver (smi). |
| 2027 __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset())); | 2027 __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset())); |
| 2028 __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset())); | 2028 __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset())); |
| 2029 // EDI: cache buckets array. | 2029 // EDI: cache buckets array. |
| 2030 // EBX: mask. | 2030 // EBX: mask. |
| 2031 __ pushl(ECX); // Spill MegamorphicCache. | 2031 __ pushl(ECX); // Spill MegamorphicCache. |
| 2032 __ movl(ECX, EAX); | 2032 |
| 2033 __ imull(ECX, Immediate(MegamorphicCache::kSpreadFactor)); | 2033 // Compute the table index. |
| 2034 ASSERT(MegamorphicCache::kSpreadFactor == 7); |
| 2035 // Use leal and subl multiply with 7 == 8 - 1. |
| 2036 __ leal(ECX, Address(EAX, TIMES_8, 0)); |
| 2037 __ subl(ECX, EAX); |
| 2034 // ECX: probe. | 2038 // ECX: probe. |
| 2035 | 2039 |
| 2036 Label loop, update, load_target_function; | 2040 Label loop, update, load_target_function; |
| 2037 __ jmp(&loop); | 2041 __ jmp(&loop); |
| 2038 | 2042 |
| 2039 __ Bind(&update); | 2043 __ Bind(&update); |
| 2040 __ addl(ECX, Immediate(Smi::RawValue(1))); | 2044 __ addl(ECX, Immediate(Smi::RawValue(1))); |
| 2041 __ Bind(&loop); | 2045 __ Bind(&loop); |
| 2042 __ andl(ECX, EBX); | 2046 __ andl(ECX, EBX); |
| 2043 const intptr_t base = Array::data_offset(); | 2047 const intptr_t base = Array::data_offset(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2063 } | 2067 } |
| 2064 | 2068 |
| 2065 | 2069 |
| 2066 // Called from megamorphic calls. | 2070 // Called from megamorphic calls. |
| 2067 // EBX: receiver | 2071 // EBX: receiver |
| 2068 // ECX: MegamorphicCache (preserved) | 2072 // ECX: MegamorphicCache (preserved) |
| 2069 // Result: | 2073 // Result: |
| 2070 // EBX: target entry point | 2074 // EBX: target entry point |
| 2071 // EDX: argument descriptor | 2075 // EDX: argument descriptor |
| 2072 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2076 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2073 EmitMegamorphicLookup(assembler); | 2077 // Jump if receiver is a smi. |
| 2078 Label smi_case; |
| 2079 // Check if object (in tmp) is a Smi. |
| 2080 __ testl(EBX, Immediate(kSmiTagMask)); |
| 2081 // Jump out of line for smi case. |
| 2082 __ j(ZERO, &smi_case, Assembler::kNearJump); |
| 2083 |
| 2084 // Loads the cid of the instance. |
| 2085 __ LoadClassId(EAX, EBX); |
| 2086 |
| 2087 Label cid_loaded; |
| 2088 __ Bind(&cid_loaded); |
| 2089 __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset())); |
| 2090 __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset())); |
| 2091 // EDI: cache buckets array. |
| 2092 // EBX: mask. |
| 2093 |
| 2094 // Tag cid as a smi. |
| 2095 __ addl(EAX, EAX); |
| 2096 |
| 2097 // Compute the table index. |
| 2098 ASSERT(MegamorphicCache::kSpreadFactor == 7); |
| 2099 // Use leal and subl multiply with 7 == 8 - 1. |
| 2100 __ leal(EDX, Address(EAX, TIMES_8, 0)); |
| 2101 __ subl(EDX, EAX); |
| 2102 |
| 2103 Label loop; |
| 2104 __ Bind(&loop); |
| 2105 __ andl(EDX, EBX); |
| 2106 |
| 2107 const intptr_t base = Array::data_offset(); |
| 2108 Label probe_failed; |
| 2109 // EDX is smi tagged, but table entries are two words, so TIMES_4. |
| 2110 __ cmpl(EAX, FieldAddress(EDI, EDX, TIMES_4, base)); |
| 2111 __ j(NOT_EQUAL, &probe_failed, Assembler::kNearJump); |
| 2112 |
| 2113 Label load_target; |
| 2114 __ Bind(&load_target); |
| 2115 // Call the target found in the cache. For a class id match, this is a |
| 2116 // proper target for the given name and arguments descriptor. If the |
| 2117 // illegal class id was found, the target is a cache miss handler that can |
| 2118 // be invoked as a normal Dart function. |
| 2119 __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, base + kWordSize)); |
| 2120 __ movl(EDX, |
| 2121 FieldAddress(ECX, MegamorphicCache::arguments_descriptor_offset())); |
| 2122 __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset())); |
| 2074 __ ret(); | 2123 __ ret(); |
| 2124 |
| 2125 __ Bind(&probe_failed); |
| 2126 // Probe failed, check if it is a miss. |
| 2127 __ cmpl(FieldAddress(EDI, EDX, TIMES_4, base), Immediate(kIllegalCid)); |
| 2128 __ j(ZERO, &load_target, Assembler::kNearJump); |
| 2129 |
| 2130 // Try next extry in the table. |
| 2131 __ AddImmediate(EDX, Immediate(Smi::RawValue(1))); |
| 2132 __ jmp(&loop); |
| 2133 |
| 2134 // Load cid for the Smi case. |
| 2135 __ Bind(&smi_case); |
| 2136 __ movl(EAX, Immediate(kSmiCid)); |
| 2137 __ jmp(&cid_loaded); |
| 2075 } | 2138 } |
| 2076 | 2139 |
| 2077 | |
| 2078 // Called from switchable IC calls. | 2140 // Called from switchable IC calls. |
| 2079 // EBX: receiver | 2141 // EBX: receiver |
| 2080 // ECX: ICData (preserved) | 2142 // ECX: ICData (preserved) |
| 2081 // Result: | 2143 // Result: |
| 2082 // EBX: target entry point | 2144 // EBX: target entry point |
| 2083 // EDX: arguments descriptor | 2145 // EDX: arguments descriptor |
| 2084 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) { | 2146 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) { |
| 2085 __ int3(); | 2147 __ int3(); |
| 2086 } | 2148 } |
| 2087 | 2149 |
| 2088 | 2150 |
| 2089 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) { | 2151 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) { |
| 2090 __ int3(); | 2152 __ int3(); |
| 2091 } | 2153 } |
| 2092 | 2154 |
| 2093 | 2155 |
| 2094 | 2156 |
| 2095 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2157 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2096 __ int3(); | 2158 __ int3(); |
| 2097 } | 2159 } |
| 2098 | 2160 |
| 2099 } // namespace dart | 2161 } // namespace dart |
| 2100 | 2162 |
| 2101 #endif // defined TARGET_ARCH_IA32 | 2163 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |