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.h" |
| 8 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
| 9 #include "src/objects.h" | 9 #include "src/objects.h" |
| 10 #include "src/type-feedback-vector-inl.h" | 10 #include "src/type-feedback-vector-inl.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 // static | 78 // static |
| 79 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( | 79 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( |
| 80 Isolate* isolate, const FeedbackVectorSpec& spec) { | 80 Isolate* isolate, const FeedbackVectorSpec& spec) { |
| 81 const int slot_count = spec.slots(); | 81 const int slot_count = spec.slots(); |
| 82 const int ic_slot_count = spec.ic_slots(); | 82 const int ic_slot_count = spec.ic_slots(); |
| 83 const int index_count = | 83 const int index_count = |
| 84 FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0; | 84 FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0; |
| 85 const int length = | 85 const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) + |
| 86 slot_count + ic_slot_count + index_count + kReservedIndexCount; | 86 index_count + kReservedIndexCount; |
| 87 if (length == kReservedIndexCount) { | 87 if (length == kReservedIndexCount) { |
| 88 return Handle<TypeFeedbackVector>::cast( | 88 return Handle<TypeFeedbackVector>::cast( |
| 89 isolate->factory()->empty_fixed_array()); | 89 isolate->factory()->empty_fixed_array()); |
| 90 } | 90 } |
| 91 | 91 |
| 92 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); | 92 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); |
| 93 if (ic_slot_count > 0) { | 93 if (ic_slot_count > 0) { |
| 94 array->set(kFirstICSlotIndex, | 94 array->set(kFirstICSlotIndex, |
| 95 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); | 95 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); |
| 96 } else { | 96 } else { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 if (!feedback->IsFixedArray() || | 200 if (!feedback->IsFixedArray() || |
| 201 FixedArray::cast(*feedback)->length() != length) { | 201 FixedArray::cast(*feedback)->length() != length) { |
| 202 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); | 202 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
| 203 SetFeedback(*array); | 203 SetFeedback(*array); |
| 204 return array; | 204 return array; |
| 205 } | 205 } |
| 206 return Handle<FixedArray>::cast(feedback); | 206 return Handle<FixedArray>::cast(feedback); |
| 207 } | 207 } |
| 208 | 208 |
| 209 | 209 |
| 210 void FeedbackNexus::InstallHandlers(int start_index, MapHandleList* maps, | 210 Handle<FixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) { |
| 211 Isolate* isolate = GetIsolate(); | |
| 212 Handle<Object> feedback_extra = handle(GetFeedbackExtra(), isolate); | |
| 213 if (!feedback_extra->IsFixedArray() || | |
| 214 FixedArray::cast(*feedback_extra)->length() != length) { | |
|
Toon Verwaest
2015/03/11 17:55:02
< ?
mvstanton
2015/03/12 17:05:34
Hmm, if the array in place is larger, then I'd hav
| |
| 215 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); | |
| 216 SetFeedbackExtra(*array); | |
| 217 return array; | |
| 218 } | |
| 219 return Handle<FixedArray>::cast(feedback_extra); | |
| 220 } | |
| 221 | |
| 222 | |
| 223 void FeedbackNexus::InstallHandlers(Handle<FixedArray> array, | |
| 224 MapHandleList* maps, | |
| 211 CodeHandleList* handlers) { | 225 CodeHandleList* handlers) { |
| 212 Isolate* isolate = GetIsolate(); | |
| 213 Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate); | |
| 214 int receiver_count = maps->length(); | 226 int receiver_count = maps->length(); |
| 215 for (int current = 0; current < receiver_count; ++current) { | 227 for (int current = 0; current < receiver_count; ++current) { |
| 216 Handle<Map> map = maps->at(current); | 228 Handle<Map> map = maps->at(current); |
| 217 Handle<WeakCell> cell = Map::WeakCellForMap(map); | 229 Handle<WeakCell> cell = Map::WeakCellForMap(map); |
| 218 array->set(start_index + (current * 2), *cell); | 230 array->set(current * 2, *cell); |
| 219 array->set(start_index + (current * 2 + 1), *handlers->at(current)); | 231 array->set(current * 2 + 1, *handlers->at(current)); |
| 220 } | 232 } |
| 221 } | 233 } |
| 222 | 234 |
| 223 | 235 |
| 224 InlineCacheState LoadICNexus::StateFromFeedback() const { | 236 InlineCacheState LoadICNexus::StateFromFeedback() const { |
| 225 Isolate* isolate = GetIsolate(); | 237 Isolate* isolate = GetIsolate(); |
| 226 Object* feedback = GetFeedback(); | 238 Object* feedback = GetFeedback(); |
| 239 | |
| 227 if (feedback == *vector()->UninitializedSentinel(isolate)) { | 240 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
| 228 return UNINITIALIZED; | 241 return UNINITIALIZED; |
| 229 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 242 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| 230 return MEGAMORPHIC; | 243 return MEGAMORPHIC; |
| 231 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { | 244 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
| 232 return PREMONOMORPHIC; | 245 return PREMONOMORPHIC; |
| 233 } else if (feedback->IsFixedArray()) { | 246 } else if (feedback->IsFixedArray()) { |
| 234 // Determine state purely by our structure, don't check if the maps are | 247 // Determine state purely by our structure, don't check if the maps are |
| 235 // cleared. | 248 // cleared. |
| 236 FixedArray* array = FixedArray::cast(feedback); | 249 return POLYMORPHIC; |
| 237 int length = array->length(); | 250 } else if (feedback->IsWeakCell()) { |
| 238 DCHECK(length >= 2); | 251 // Don't check if the map is cleared. |
| 239 return length == 2 ? MONOMORPHIC : POLYMORPHIC; | 252 return MONOMORPHIC; |
| 240 } | 253 } |
| 241 | 254 |
| 242 return UNINITIALIZED; | 255 return UNINITIALIZED; |
| 243 } | 256 } |
| 244 | 257 |
| 245 | 258 |
| 246 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { | 259 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { |
| 247 Isolate* isolate = GetIsolate(); | 260 Isolate* isolate = GetIsolate(); |
| 248 Object* feedback = GetFeedback(); | 261 Object* feedback = GetFeedback(); |
| 262 | |
| 249 if (feedback == *vector()->UninitializedSentinel(isolate)) { | 263 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
| 250 return UNINITIALIZED; | 264 return UNINITIALIZED; |
| 251 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { | 265 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
| 252 return PREMONOMORPHIC; | 266 return PREMONOMORPHIC; |
| 253 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 267 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| 254 return MEGAMORPHIC; | 268 return MEGAMORPHIC; |
| 255 } else if (feedback->IsFixedArray()) { | 269 } else if (feedback->IsFixedArray()) { |
| 256 // Determine state purely by our structure, don't check if the maps are | 270 // Determine state purely by our structure, don't check if the maps are |
| 257 // cleared. | 271 // cleared. |
| 258 FixedArray* array = FixedArray::cast(feedback); | 272 return POLYMORPHIC; |
| 259 int length = array->length(); | 273 } else if (feedback->IsWeakCell()) { |
| 260 DCHECK(length >= 3); | 274 // Don't check if the map is cleared. |
| 261 return length == 3 ? MONOMORPHIC : POLYMORPHIC; | 275 return MONOMORPHIC; |
| 276 } else if (feedback->IsName()) { | |
| 277 Object* extra = GetFeedbackExtra(); | |
| 278 FixedArray* extra_array = FixedArray::cast(extra); | |
| 279 return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC; | |
| 262 } | 280 } |
| 263 | 281 |
| 264 return UNINITIALIZED; | 282 return UNINITIALIZED; |
| 265 } | 283 } |
| 266 | 284 |
| 267 | 285 |
| 268 InlineCacheState CallICNexus::StateFromFeedback() const { | 286 InlineCacheState CallICNexus::StateFromFeedback() const { |
| 269 Isolate* isolate = GetIsolate(); | 287 Isolate* isolate = GetIsolate(); |
| 270 Object* feedback = GetFeedback(); | 288 Object* feedback = GetFeedback(); |
| 289 DCHECK(!FLAG_vector_ics || | |
| 290 GetFeedbackExtra() == *vector()->UninitializedSentinel(isolate)); | |
| 271 | 291 |
| 272 if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 292 if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| 273 return GENERIC; | 293 return GENERIC; |
| 274 } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) { | 294 } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) { |
| 275 return MONOMORPHIC; | 295 return MONOMORPHIC; |
| 276 } | 296 } |
| 277 | 297 |
| 278 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); | 298 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); |
| 279 return UNINITIALIZED; | 299 return UNINITIALIZED; |
| 280 } | 300 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 304 } | 324 } |
| 305 | 325 |
| 306 | 326 |
| 307 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { | 327 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { |
| 308 Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function); | 328 Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function); |
| 309 SetFeedback(*new_cell); | 329 SetFeedback(*new_cell); |
| 310 } | 330 } |
| 311 | 331 |
| 312 | 332 |
| 313 void KeyedLoadICNexus::ConfigureMegamorphic() { | 333 void KeyedLoadICNexus::ConfigureMegamorphic() { |
| 314 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); | 334 Isolate* isolate = GetIsolate(); |
| 335 SetFeedback(*vector()->MegamorphicSentinel(isolate), SKIP_WRITE_BARRIER); | |
| 336 SetFeedbackExtra(*vector()->UninitializedSentinel(isolate), | |
| 337 SKIP_WRITE_BARRIER); | |
| 315 } | 338 } |
| 316 | 339 |
| 317 | 340 |
| 318 void LoadICNexus::ConfigureMegamorphic() { | 341 void LoadICNexus::ConfigureMegamorphic() { |
| 319 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); | 342 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); |
| 343 SetFeedbackExtra(*vector()->UninitializedSentinel(GetIsolate()), | |
| 344 SKIP_WRITE_BARRIER); | |
| 320 } | 345 } |
| 321 | 346 |
| 322 | 347 |
| 323 void LoadICNexus::ConfigurePremonomorphic() { | 348 void LoadICNexus::ConfigurePremonomorphic() { |
| 324 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), | 349 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), |
| 325 SKIP_WRITE_BARRIER); | 350 SKIP_WRITE_BARRIER); |
| 351 SetFeedbackExtra(*vector()->UninitializedSentinel(GetIsolate()), | |
| 352 SKIP_WRITE_BARRIER); | |
| 326 } | 353 } |
| 327 | 354 |
| 328 | 355 |
| 329 void KeyedLoadICNexus::ConfigurePremonomorphic() { | 356 void KeyedLoadICNexus::ConfigurePremonomorphic() { |
| 330 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), | 357 Isolate* isolate = GetIsolate(); |
| 331 SKIP_WRITE_BARRIER); | 358 SetFeedback(*vector()->PremonomorphicSentinel(isolate), SKIP_WRITE_BARRIER); |
| 359 SetFeedbackExtra(*vector()->UninitializedSentinel(isolate), | |
| 360 SKIP_WRITE_BARRIER); | |
| 332 } | 361 } |
| 333 | 362 |
| 334 | 363 |
| 335 void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, | 364 void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, |
| 336 Handle<Code> handler) { | 365 Handle<Code> handler) { |
| 337 Handle<FixedArray> array = EnsureArrayOfSize(2); | |
| 338 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | 366 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 339 array->set(0, *cell); | 367 SetFeedback(*cell); |
| 340 array->set(1, *handler); | 368 SetFeedbackExtra(*handler); |
| 341 } | 369 } |
| 342 | 370 |
| 343 | 371 |
| 344 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, | 372 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, |
| 345 Handle<Map> receiver_map, | 373 Handle<Map> receiver_map, |
| 346 Handle<Code> handler) { | 374 Handle<Code> handler) { |
| 347 Handle<FixedArray> array = EnsureArrayOfSize(3); | 375 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 348 if (name.is_null()) { | 376 if (name.is_null()) { |
| 349 array->set(0, Smi::FromInt(0)); | 377 SetFeedback(*cell); |
| 378 SetFeedbackExtra(*handler); | |
| 350 } else { | 379 } else { |
| 351 array->set(0, *name); | 380 SetFeedback(*name); |
| 381 Handle<FixedArray> array = EnsureExtraArrayOfSize(2); | |
| 382 array->set(0, *cell); | |
| 383 array->set(1, *handler); | |
| 352 } | 384 } |
| 353 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | |
| 354 array->set(1, *cell); | |
| 355 array->set(2, *handler); | |
| 356 } | 385 } |
| 357 | 386 |
| 358 | 387 |
| 359 void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, | 388 void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, |
| 360 CodeHandleList* handlers) { | 389 CodeHandleList* handlers) { |
| 390 Isolate* isolate = GetIsolate(); | |
| 361 int receiver_count = maps->length(); | 391 int receiver_count = maps->length(); |
| 362 EnsureArrayOfSize(receiver_count * 2); | 392 Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); |
| 363 InstallHandlers(0, maps, handlers); | 393 InstallHandlers(array, maps, handlers); |
| 394 SetFeedbackExtra(*vector()->UninitializedSentinel(isolate), | |
| 395 SKIP_WRITE_BARRIER); | |
| 364 } | 396 } |
| 365 | 397 |
| 366 | 398 |
| 367 void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, | 399 void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, |
| 368 MapHandleList* maps, | 400 MapHandleList* maps, |
| 369 CodeHandleList* handlers) { | 401 CodeHandleList* handlers) { |
| 370 int receiver_count = maps->length(); | 402 int receiver_count = maps->length(); |
| 371 Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2); | 403 DCHECK(receiver_count > 1); |
| 404 Handle<FixedArray> array; | |
| 372 if (name.is_null()) { | 405 if (name.is_null()) { |
| 373 array->set(0, Smi::FromInt(0)); | 406 array = EnsureArrayOfSize(receiver_count * 2); |
| 407 SetFeedbackExtra(*vector()->UninitializedSentinel(GetIsolate()), | |
| 408 SKIP_WRITE_BARRIER); | |
| 374 } else { | 409 } else { |
| 375 array->set(0, *name); | 410 SetFeedback(*name); |
| 411 array = EnsureExtraArrayOfSize(receiver_count * 2); | |
| 376 } | 412 } |
| 377 InstallHandlers(1, maps, handlers); | 413 |
| 414 InstallHandlers(array, maps, handlers); | |
| 378 } | 415 } |
| 379 | 416 |
| 380 | 417 |
| 381 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { | 418 int FeedbackNexus::ExtractMapsImpl(MapHandleList* maps) const { |
| 382 Isolate* isolate = GetIsolate(); | 419 Isolate* isolate = GetIsolate(); |
| 383 Object* feedback = GetFeedback(); | 420 Object* feedback = GetFeedback(); |
| 384 if (feedback->IsFixedArray()) { | 421 if (feedback->IsFixedArray() || feedback->IsString()) { |
| 385 int found = 0; | 422 int found = 0; |
| 423 if (feedback->IsString()) { | |
| 424 feedback = GetFeedbackExtra(); | |
| 425 } | |
| 386 FixedArray* array = FixedArray::cast(feedback); | 426 FixedArray* array = FixedArray::cast(feedback); |
| 387 // The array should be of the form [<optional name>], then | 427 // The array should be of the form [<optional name>], then |
| 388 // [map, handler, map, handler, ... ] | 428 // [map, handler, map, handler, ... ] |
| 389 DCHECK(array->length() >= (2 + start_index)); | 429 DCHECK(array->length() >= 2); |
| 390 for (int i = start_index; i < array->length(); i += 2) { | 430 for (int i = 0; i < array->length(); i += 2) { |
| 391 WeakCell* cell = WeakCell::cast(array->get(i)); | 431 WeakCell* cell = WeakCell::cast(array->get(i)); |
| 392 if (!cell->cleared()) { | 432 if (!cell->cleared()) { |
| 393 Map* map = Map::cast(cell->value()); | 433 Map* map = Map::cast(cell->value()); |
| 394 maps->Add(handle(map, isolate)); | 434 maps->Add(handle(map, isolate)); |
| 395 found++; | 435 found++; |
| 396 } | 436 } |
| 397 } | 437 } |
| 398 return found; | 438 return found; |
| 439 } else if (feedback->IsWeakCell()) { | |
| 440 WeakCell* cell = WeakCell::cast(feedback); | |
| 441 if (!cell->cleared()) { | |
| 442 Map* map = Map::cast(cell->value()); | |
| 443 maps->Add(handle(map, isolate)); | |
| 444 return 1; | |
| 445 } | |
| 399 } | 446 } |
| 400 | 447 |
| 401 return 0; | 448 return 0; |
| 402 } | 449 } |
| 403 | 450 |
| 404 | 451 |
| 405 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, | 452 MaybeHandle<Code> FeedbackNexus::FindHandlerForMapImpl(Handle<Map> map) const { |
| 406 Handle<Map> map) const { | |
| 407 Object* feedback = GetFeedback(); | 453 Object* feedback = GetFeedback(); |
| 408 if (feedback->IsFixedArray()) { | 454 if (feedback->IsFixedArray() || feedback->IsString()) { |
| 455 if (feedback->IsString()) { | |
| 456 feedback = GetFeedbackExtra(); | |
| 457 } | |
| 409 FixedArray* array = FixedArray::cast(feedback); | 458 FixedArray* array = FixedArray::cast(feedback); |
| 410 for (int i = start_index; i < array->length(); i += 2) { | 459 for (int i = 0; i < array->length(); i += 2) { |
| 411 WeakCell* cell = WeakCell::cast(array->get(i)); | 460 WeakCell* cell = WeakCell::cast(array->get(i)); |
| 412 if (!cell->cleared()) { | 461 if (!cell->cleared()) { |
| 413 Map* array_map = Map::cast(cell->value()); | 462 Map* array_map = Map::cast(cell->value()); |
| 414 if (array_map == *map) { | 463 if (array_map == *map) { |
| 415 Code* code = Code::cast(array->get(i + 1)); | 464 Code* code = Code::cast(array->get(i + 1)); |
| 416 DCHECK(code->kind() == Code::HANDLER); | 465 DCHECK(code->kind() == Code::HANDLER); |
| 417 return handle(code); | 466 return handle(code); |
| 418 } | 467 } |
| 419 } | 468 } |
| 420 } | 469 } |
| 470 } else if (feedback->IsWeakCell()) { | |
| 471 WeakCell* cell = WeakCell::cast(feedback); | |
| 472 if (!cell->cleared()) { | |
| 473 Map* cell_map = Map::cast(cell->value()); | |
| 474 if (cell_map == *map) { | |
| 475 Code* code = Code::cast(GetFeedbackExtra()); | |
| 476 DCHECK(code->kind() == Code::HANDLER); | |
| 477 return handle(code); | |
| 478 } | |
| 479 } | |
| 421 } | 480 } |
| 422 | 481 |
| 423 return MaybeHandle<Code>(); | 482 return MaybeHandle<Code>(); |
| 424 } | 483 } |
| 425 | 484 |
| 426 | 485 |
| 427 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, | 486 bool FeedbackNexus::FindHandlersImpl(CodeHandleList* code_list, |
| 428 int length) const { | 487 int length) const { |
| 429 Object* feedback = GetFeedback(); | 488 Object* feedback = GetFeedback(); |
| 430 int count = 0; | 489 int count = 0; |
| 431 if (feedback->IsFixedArray()) { | 490 if (feedback->IsFixedArray() || feedback->IsString()) { |
| 491 if (feedback->IsString()) { | |
| 492 feedback = GetFeedbackExtra(); | |
| 493 } | |
| 432 FixedArray* array = FixedArray::cast(feedback); | 494 FixedArray* array = FixedArray::cast(feedback); |
| 433 // The array should be of the form [<optional name>], then | 495 // The array should be of the form [map, handler, map, handler, ... ]. |
| 434 // [map, handler, map, handler, ... ]. Be sure to skip handlers whose maps | 496 // Be sure to skip handlers whose maps have been cleared. |
| 435 // have been cleared. | 497 DCHECK(array->length() >= 2); |
| 436 DCHECK(array->length() >= (2 + start_index)); | 498 for (int i = 0; i < array->length(); i += 2) { |
| 437 for (int i = start_index; i < array->length(); i += 2) { | |
| 438 WeakCell* cell = WeakCell::cast(array->get(i)); | 499 WeakCell* cell = WeakCell::cast(array->get(i)); |
| 439 if (!cell->cleared()) { | 500 if (!cell->cleared()) { |
| 440 Code* code = Code::cast(array->get(i + 1)); | 501 Code* code = Code::cast(array->get(i + 1)); |
| 441 DCHECK(code->kind() == Code::HANDLER); | 502 DCHECK(code->kind() == Code::HANDLER); |
| 442 code_list->Add(handle(code)); | 503 code_list->Add(handle(code)); |
| 443 count++; | 504 count++; |
| 444 } | 505 } |
| 445 } | 506 } |
| 507 } else if (feedback->IsWeakCell()) { | |
| 508 WeakCell* cell = WeakCell::cast(feedback); | |
| 509 if (!cell->cleared()) { | |
| 510 Code* code = Code::cast(GetFeedbackExtra()); | |
| 511 DCHECK(code->kind() == Code::HANDLER); | |
| 512 code_list->Add(handle(code)); | |
| 513 count++; | |
| 514 } | |
| 446 } | 515 } |
| 447 return count == length; | 516 return count == length; |
| 448 } | 517 } |
| 449 | 518 |
| 450 | 519 |
| 451 int LoadICNexus::ExtractMaps(MapHandleList* maps) const { | 520 int LoadICNexus::ExtractMaps(MapHandleList* maps) const { |
| 452 return FeedbackNexus::ExtractMaps(0, maps); | 521 return FeedbackNexus::ExtractMapsImpl(maps); |
| 453 } | 522 } |
| 454 | 523 |
| 455 | 524 |
| 456 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } | 525 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } |
| 457 | 526 |
| 458 | 527 |
| 459 void KeyedLoadICNexus::Clear(Code* host) { | 528 void KeyedLoadICNexus::Clear(Code* host) { |
| 460 KeyedLoadIC::Clear(GetIsolate(), host, this); | 529 KeyedLoadIC::Clear(GetIsolate(), host, this); |
| 461 } | 530 } |
| 462 | 531 |
| 463 | 532 |
| 464 int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const { | 533 int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const { |
| 465 return FeedbackNexus::ExtractMaps(1, maps); | 534 return FeedbackNexus::ExtractMapsImpl(maps); |
| 466 } | 535 } |
| 467 | 536 |
| 468 | 537 |
| 469 MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const { | 538 MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const { |
| 470 return FeedbackNexus::FindHandlerForMap(0, map); | 539 return FeedbackNexus::FindHandlerForMapImpl(map); |
| 471 } | 540 } |
| 472 | 541 |
| 473 | 542 |
| 474 MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const { | 543 MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const { |
| 475 return FeedbackNexus::FindHandlerForMap(1, map); | 544 return FeedbackNexus::FindHandlerForMapImpl(map); |
| 476 } | 545 } |
| 477 | 546 |
| 478 | 547 |
| 479 bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const { | 548 bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const { |
| 480 return FeedbackNexus::FindHandlers(0, code_list, length); | 549 return FeedbackNexus::FindHandlersImpl(code_list, length); |
| 481 } | 550 } |
| 482 | 551 |
| 483 | 552 |
| 484 bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list, | 553 bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list, |
| 485 int length) const { | 554 int length) const { |
| 486 return FeedbackNexus::FindHandlers(1, code_list, length); | 555 return FeedbackNexus::FindHandlersImpl(code_list, length); |
| 487 } | 556 } |
| 488 | 557 |
| 489 | 558 |
| 490 Name* KeyedLoadICNexus::FindFirstName() const { | 559 Name* KeyedLoadICNexus::FindFirstName() const { |
| 491 Object* feedback = GetFeedback(); | 560 Object* feedback = GetFeedback(); |
| 492 if (feedback->IsFixedArray()) { | 561 if (feedback->IsString()) { |
| 493 FixedArray* array = FixedArray::cast(feedback); | 562 return Name::cast(feedback); |
| 494 DCHECK(array->length() >= 3); | |
| 495 Object* name = array->get(0); | |
| 496 if (name->IsName()) return Name::cast(name); | |
| 497 } | 563 } |
| 498 return NULL; | 564 return NULL; |
| 499 } | 565 } |
| 500 } | 566 } |
| 501 } // namespace v8::internal | 567 } // namespace v8::internal |
| OLD | NEW |