Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/ic/ic.h" | |
| 7 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
| 8 #include "src/objects.h" | 9 #include "src/objects.h" |
| 9 #include "src/type-feedback-vector-inl.h" | 10 #include "src/type-feedback-vector-inl.h" |
| 10 | 11 |
| 11 namespace v8 { | 12 namespace v8 { |
| 12 namespace internal { | 13 namespace internal { |
| 13 | 14 |
| 14 // static | 15 // static |
| 15 TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind( | 16 TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind( |
| 16 Code::Kind kind) { | 17 Code::Kind kind) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 slots = ICSlots(); | 139 slots = ICSlots(); |
| 139 if (slots == 0) return; | 140 if (slots == 0) return; |
| 140 | 141 |
| 141 // Now clear vector-based ICs. They are all CallICs. | 142 // Now clear vector-based ICs. They are all CallICs. |
| 142 // Try and pass the containing code (the "host"). | 143 // Try and pass the containing code (the "host"). |
| 143 Code* host = shared->code(); | 144 Code* host = shared->code(); |
| 144 for (int i = 0; i < slots; i++) { | 145 for (int i = 0; i < slots; i++) { |
| 145 FeedbackVectorICSlot slot(i); | 146 FeedbackVectorICSlot slot(i); |
| 146 Object* obj = Get(slot); | 147 Object* obj = Get(slot); |
| 147 if (obj != uninitialized_sentinel) { | 148 if (obj != uninitialized_sentinel) { |
| 148 ICUtility::Clear(isolate, Code::CALL_IC, host, this, slot); | 149 // TODO(mvstanton): To make this code work with --vector-ics, |
| 150 // additional Nexus types must be created. | |
| 151 DCHECK(!FLAG_vector_ics); | |
| 152 DCHECK(GetKind(slot) == Code::CALL_IC); | |
| 153 CallICNexus nexus(this, slot); | |
| 154 ICUtility::Clear(isolate, Code::CALL_IC, host, &nexus); | |
| 149 } | 155 } |
| 150 } | 156 } |
| 151 } | 157 } |
| 158 | |
| 159 | |
| 160 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { | |
| 161 Isolate* isolate = GetIsolate(); | |
| 162 Handle<Object> feedback = handle(GetFeedback(), isolate); | |
| 163 if (!feedback->IsFixedArray() || | |
| 164 FixedArray::cast(*feedback)->length() != length) { | |
|
Igor Sheludko
2014/10/28 11:12:36
Do we need to allocate another array if existing o
mvstanton
2014/10/28 13:23:28
Hmm, the only case that would happen would be if t
| |
| 165 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); | |
| 166 SetFeedback(*array); | |
| 167 return array; | |
| 168 } | |
| 169 return Handle<FixedArray>::cast(feedback); | |
| 170 } | |
| 171 | |
| 172 | |
| 173 void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, | |
| 174 CodeHandleList* handlers) { | |
| 175 Isolate* isolate = GetIsolate(); | |
| 176 FixedArray* array = FixedArray::cast(GetFeedback()); | |
| 177 int receiver_count = types->length(); | |
| 178 for (int current = 0; current < receiver_count; ++current) { | |
| 179 Handle<HeapType> type = types->at(current); | |
| 180 Handle<Map> map = IC::TypeToMap(*type, isolate); | |
| 181 array->set(start_index + (current * 2), *map); | |
| 182 array->set(start_index + (current * 2 + 1), *handlers->at(current)); | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 | |
| 187 InlineCacheState CallICNexus::StateFromFeedback() const { | |
| 188 Isolate* isolate = GetIsolate(); | |
| 189 InlineCacheState state = UNINITIALIZED; | |
| 190 Object* feedback = GetFeedback(); | |
| 191 | |
| 192 if (feedback == *vector()->MegamorphicSentinel(isolate)) { | |
| 193 state = GENERIC; | |
| 194 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { | |
| 195 state = MONOMORPHIC; | |
| 196 } else { | |
| 197 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); | |
| 198 } | |
| 199 | |
| 200 return state; | |
| 201 } | |
| 202 | |
| 203 | |
| 204 void CallICNexus::ConfigureGeneric() { | |
| 205 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate())); | |
| 206 } | |
| 207 | |
| 208 | |
| 209 void CallICNexus::ConfigureMonomorphicArray() { | |
| 210 Object* feedback = GetFeedback(); | |
| 211 if (!feedback->IsAllocationSite()) { | |
| 212 Handle<AllocationSite> new_site = | |
| 213 GetIsolate()->factory()->NewAllocationSite(); | |
| 214 SetFeedback(*new_site); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 | |
| 219 void CallICNexus::ConfigureUninitialized() { | |
| 220 SetFeedback(*vector()->UninitializedSentinel(GetIsolate())); | |
| 221 } | |
| 222 | |
| 223 | |
| 224 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { | |
| 225 SetFeedback(*function); | |
| 226 } | |
| 227 | |
|
Igor Sheludko
2014/10/28 11:12:36
Empty line is missing.
mvstanton
2014/10/28 13:23:28
Done.
| |
| 228 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { | |
| 229 Isolate* isolate = GetIsolate(); | |
| 230 Object* feedback = GetFeedback(); | |
| 231 if (feedback->IsFixedArray()) { | |
| 232 FixedArray* array = FixedArray::cast(feedback); | |
| 233 // The array should be of the form [<optional name>], then | |
| 234 // [map, handler, map, handler, ... ] | |
| 235 DCHECK(array->length() >= (2 + start_index)); | |
| 236 for (int i = start_index; i < array->length(); i += 2) { | |
| 237 Map* map = Map::cast(array->get(i)); | |
| 238 maps->Add(handle(map, isolate)); | |
| 239 } | |
| 240 return (array->length() - start_index) / 2; | |
| 241 } | |
| 242 | |
| 243 return 0; | |
| 244 } | |
| 245 | |
| 246 | |
| 247 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, | |
| 248 Handle<Map> map) const { | |
| 249 Object* feedback = GetFeedback(); | |
| 250 if (feedback->IsFixedArray()) { | |
| 251 FixedArray* array = FixedArray::cast(feedback); | |
| 252 for (int i = start_index; i < array->length(); i += 2) { | |
| 253 Map* array_map = Map::cast(array->get(i)); | |
| 254 if (array_map == *map) { | |
| 255 Code* code = Code::cast(array->get(i + 1)); | |
| 256 DCHECK(code->kind() == Code::HANDLER); | |
| 257 return handle(code); | |
| 258 } | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 return MaybeHandle<Code>(); | |
| 263 } | |
| 264 | |
| 265 | |
| 266 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, | |
| 267 int length) const { | |
| 268 Object* feedback = GetFeedback(); | |
| 269 int count = 0; | |
| 270 if (feedback->IsFixedArray()) { | |
| 271 FixedArray* array = FixedArray::cast(feedback); | |
| 272 // The array should be of the form [<optional name>], then | |
| 273 // [map, handler, map, handler, ... ] | |
| 274 DCHECK(array->length() >= (2 + start_index)); | |
| 275 for (int i = start_index; i < array->length(); i += 2) { | |
| 276 Code* code = Code::cast(array->get(i + 1)); | |
| 277 DCHECK(code->kind() == Code::HANDLER); | |
| 278 code_list->Add(handle(code)); | |
| 279 count++; | |
| 280 } | |
| 281 } | |
| 282 return count == length; | |
| 283 } | |
| 152 } | 284 } |
| 153 } // namespace v8::internal | 285 } // namespace v8::internal |
| OLD | NEW |