Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: runtime/vm/stub_code_x64.cc

Issue 2226893002: Optimize AOT's switchable calls for the monomorphic case. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: . Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« runtime/vm/profiler.cc ('K') | « runtime/vm/stub_code_mips.cc ('k') | runtime/vm/thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698