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