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_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 1998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2009 | 2009 |
2010 | 2010 |
2011 // Called from megamorphic calls. | 2011 // Called from megamorphic calls. |
2012 // RDI: receiver | 2012 // RDI: receiver |
2013 // RBX: MegamorphicCache (preserved) | 2013 // RBX: MegamorphicCache (preserved) |
2014 // Result: | 2014 // Result: |
2015 // RCX: target entry point | 2015 // RCX: target entry point |
2016 // CODE_REG: target Code | 2016 // CODE_REG: target Code |
2017 // R10: arguments descriptor | 2017 // R10: arguments descriptor |
2018 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2018 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2019 __ NoMonomorphicCheckedEntry(); | |
2020 | |
2019 // Jump if receiver is a smi. | 2021 // Jump if receiver is a smi. |
2020 Label smi_case; | 2022 Label smi_case; |
2021 __ testq(RDI, Immediate(kSmiTagMask)); | 2023 __ testq(RDI, Immediate(kSmiTagMask)); |
2022 // Jump out of line for smi case. | 2024 // Jump out of line for smi case. |
2023 __ j(ZERO, &smi_case, Assembler::kNearJump); | 2025 __ j(ZERO, &smi_case, Assembler::kNearJump); |
2024 | 2026 |
2025 // Loads the cid of the object. | 2027 // Loads the cid of the object. |
2026 __ LoadClassId(RAX, RDI); | 2028 __ LoadClassId(RAX, RDI); |
2027 | 2029 |
2028 Label cid_loaded; | 2030 Label cid_loaded; |
(...skipping 26 matching lines...) Expand all Loading... | |
2055 __ Bind(&load_target); | 2057 __ Bind(&load_target); |
2056 // Call the target found in the cache. For a class id match, this is a | 2058 // Call the target found in the cache. For a class id match, this is a |
2057 // proper target for the given name and arguments descriptor. If the | 2059 // proper target for the given name and arguments descriptor. If the |
2058 // illegal class id was found, the target is a cache miss handler that can | 2060 // illegal class id was found, the target is a cache miss handler that can |
2059 // be invoked as a normal Dart function. | 2061 // be invoked as a normal Dart function. |
2060 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); | 2062 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); |
2061 __ movq(R10, | 2063 __ movq(R10, |
2062 FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset())); | 2064 FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset())); |
2063 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); | 2065 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
2064 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); | 2066 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
2065 | 2067 __ jmp(RCX); |
2066 __ ret(); | |
2067 | 2068 |
2068 // Probe failed, check if it is a miss. | 2069 // Probe failed, check if it is a miss. |
2069 __ Bind(&probe_failed); | 2070 __ Bind(&probe_failed); |
2070 __ cmpq(FieldAddress(RDI, RCX, TIMES_8, base), Immediate(kIllegalCid)); | 2071 __ cmpq(FieldAddress(RDI, RCX, TIMES_8, base), Immediate(kIllegalCid)); |
2071 __ j(ZERO, &load_target, Assembler::kNearJump); | 2072 __ j(ZERO, &load_target, Assembler::kNearJump); |
2072 | 2073 |
2073 // Try next extry in the table. | 2074 // Try next extry in the table. |
2074 __ AddImmediate(RCX, Immediate(Smi::RawValue(1))); | 2075 __ AddImmediate(RCX, Immediate(Smi::RawValue(1))); |
2075 __ jmp(&loop); | 2076 __ jmp(&loop); |
2076 | 2077 |
2077 // Load cid for the Smi case. | 2078 // Load cid for the Smi case. |
2078 __ Bind(&smi_case); | 2079 __ Bind(&smi_case); |
2079 __ movq(RAX, Immediate(kSmiCid)); | 2080 __ movq(RAX, Immediate(kSmiCid)); |
2080 __ jmp(&cid_loaded); | 2081 __ jmp(&cid_loaded); |
2081 } | 2082 } |
2082 | 2083 |
2083 | 2084 |
2084 // Called from switchable IC calls. | 2085 // Called from switchable IC calls. |
2085 // RDI: receiver | 2086 // RDI: receiver |
2086 // RBX: ICData (preserved) | 2087 // RBX: ICData (preserved) |
2087 // Result: | 2088 // Result: |
2088 // RCX: target entry point | 2089 // RCX: target entry point |
2089 // CODE_REG: target Code object | 2090 // CODE_REG: target Code object |
2090 // R10: arguments descriptor | 2091 // R10: arguments descriptor |
2091 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) { | 2092 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) { |
2093 __ NoMonomorphicCheckedEntry(); | |
2094 | |
2092 Label loop, found, miss; | 2095 Label loop, found, miss; |
2093 | 2096 |
2094 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); | 2097 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); |
2095 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 2098 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
2096 __ leaq(R13, FieldAddress(R13, Array::data_offset())); | 2099 __ leaq(R13, FieldAddress(R13, Array::data_offset())); |
2097 // R13: first IC entry | 2100 // R13: first IC entry |
2098 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); | 2101 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); |
2099 // RAX: receiver cid as Smi | 2102 // RAX: receiver cid as Smi |
2100 | 2103 |
2101 __ Bind(&loop); | 2104 __ Bind(&loop); |
2102 __ movq(R9, Address(R13, 0)); | 2105 __ movq(R9, Address(R13, 0)); |
2103 __ cmpq(RAX, R9); | 2106 __ cmpq(RAX, R9); |
2104 __ j(EQUAL, &found, Assembler::kNearJump); | 2107 __ j(EQUAL, &found, Assembler::kNearJump); |
2105 | 2108 |
2106 ASSERT(Smi::RawValue(kIllegalCid) == 0); | 2109 ASSERT(Smi::RawValue(kIllegalCid) == 0); |
2107 __ testq(R9, R9); | 2110 __ testq(R9, R9); |
2108 __ j(ZERO, &miss, Assembler::kNearJump); | 2111 __ j(ZERO, &miss, Assembler::kNearJump); |
2109 | 2112 |
2110 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; | 2113 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; |
2111 __ addq(R13, Immediate(entry_length)); // Next entry. | 2114 __ addq(R13, Immediate(entry_length)); // Next entry. |
2112 __ jmp(&loop); | 2115 __ jmp(&loop); |
2113 | 2116 |
2114 __ Bind(&found); | 2117 __ Bind(&found); |
2115 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; | 2118 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; |
2116 __ movq(RAX, Address(R13, target_offset)); | 2119 __ movq(RAX, Address(R13, target_offset)); |
2117 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); | 2120 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
2118 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); | 2121 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
2119 __ ret(); | 2122 __ jmp(RCX); |
2120 | 2123 |
2121 __ Bind(&miss); | 2124 __ Bind(&miss); |
2122 __ LoadIsolate(RAX); | 2125 __ LoadIsolate(RAX); |
2123 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); | 2126 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); |
2124 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2127 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
2125 __ ret(); | 2128 __ jmp(RCX); |
2126 } | 2129 } |
2127 | 2130 |
2128 | 2131 |
2129 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) { | 2132 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) { |
2133 __ NoMonomorphicCheckedEntry(); | |
2134 | |
2130 Label loop, found, miss; | 2135 Label loop, found, miss; |
2131 | 2136 |
2132 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); | 2137 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); |
2133 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 2138 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
2134 __ leaq(R13, FieldAddress(R13, Array::data_offset())); | 2139 __ leaq(R13, FieldAddress(R13, Array::data_offset())); |
2135 // R13: first IC entry | 2140 // R13: first IC entry |
2136 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); | 2141 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); |
2137 // RAX: receiver cid as Smi | 2142 // RAX: receiver cid as Smi |
2138 | 2143 |
2139 __ Bind(&loop); | 2144 __ Bind(&loop); |
2140 __ movq(R9, Address(R13, 0)); | 2145 __ movq(R9, Address(R13, 0)); |
2141 __ cmpq(RAX, R9); | 2146 __ cmpq(RAX, R9); |
2142 __ j(EQUAL, &found, Assembler::kNearJump); | 2147 __ j(EQUAL, &found, Assembler::kNearJump); |
2143 | 2148 |
2144 ASSERT(Smi::RawValue(kIllegalCid) == 0); | 2149 ASSERT(Smi::RawValue(kIllegalCid) == 0); |
2145 __ testq(R9, R9); | 2150 __ testq(R9, R9); |
2146 __ j(ZERO, &miss, Assembler::kNearJump); | 2151 __ j(ZERO, &miss, Assembler::kNearJump); |
2147 | 2152 |
2148 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; | 2153 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; |
2149 __ addq(R13, Immediate(entry_length)); // Next entry. | 2154 __ addq(R13, Immediate(entry_length)); // Next entry. |
2150 __ jmp(&loop); | 2155 __ jmp(&loop); |
2151 | 2156 |
2152 __ Bind(&found); | 2157 __ Bind(&found); |
2153 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize; | 2158 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize; |
2154 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize; | 2159 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize; |
2155 __ movq(RCX, Address(R13, entry_offset)); | 2160 __ movq(RCX, Address(R13, entry_offset)); |
2156 __ movq(CODE_REG, Address(R13, code_offset)); | 2161 __ movq(CODE_REG, Address(R13, code_offset)); |
2157 __ ret(); | 2162 __ jmp(RCX); |
2158 | 2163 |
2159 __ Bind(&miss); | 2164 __ Bind(&miss); |
2160 __ LoadIsolate(RAX); | 2165 __ LoadIsolate(RAX); |
2161 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); | 2166 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); |
2162 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2167 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
2163 __ ret(); | 2168 __ jmp(RCX); |
2164 } | 2169 } |
2165 | 2170 |
2166 | 2171 |
2172 | |
2173 // RDI: receiver | |
2174 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) { | |
2175 __ EnterStubFrame(); | |
2176 __ pushq(RDI); // Preserve receiver. | |
2177 | |
2178 __ PushObject(Object::null_object()); // Result. | |
2179 __ pushq(RDI); // Arg0: Receiver / stub out | |
Florian Schneider
2016/08/10 02:32:14
formatting: align //
rmacnak
2016/08/11 00:17:49
Done.
| |
2180 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1); | |
2181 __ popq(CODE_REG); | |
2182 __ popq(RBX); // result = IC | |
2183 | |
2184 __ popq(RDI); // Restore receiver. | |
2185 __ LeaveStubFrame(); | |
2186 | |
2187 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | |
2188 __ jmp(RCX); | |
2189 } | |
2190 | |
2191 | |
2167 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2192 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
2168 __ int3(); | 2193 __ int3(); |
2169 } | 2194 } |
2170 | 2195 |
2171 } // namespace dart | 2196 } // namespace dart |
2172 | 2197 |
2173 #endif // defined TARGET_ARCH_X64 | 2198 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |