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