| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/ast.h" | 7 #include "src/ast.h" | 
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" | 
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" | 
| 10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 74 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { | 74 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { | 
| 75   Handle<Object> maybe_code = GetInfo(id); | 75   Handle<Object> maybe_code = GetInfo(id); | 
| 76   if (maybe_code->IsCode()) { | 76   if (maybe_code->IsCode()) { | 
| 77     Handle<Code> code = Handle<Code>::cast(maybe_code); | 77     Handle<Code> code = Handle<Code>::cast(maybe_code); | 
| 78     return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; | 78     return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; | 
| 79   } | 79   } | 
| 80   return false; | 80   return false; | 
| 81 } | 81 } | 
| 82 | 82 | 
| 83 | 83 | 
|  | 84 bool TypeFeedbackOracle::LoadIsUninitialized(FeedbackVectorICSlot slot) { | 
|  | 85   Code::Kind kind = feedback_vector_->GetKind(slot); | 
|  | 86   if (kind == Code::LOAD_IC) { | 
|  | 87     LoadICNexus nexus(feedback_vector_, slot); | 
|  | 88     return nexus.StateFromFeedback() == UNINITIALIZED; | 
|  | 89   } else if (kind == Code::KEYED_LOAD_IC) { | 
|  | 90     KeyedLoadICNexus nexus(feedback_vector_, slot); | 
|  | 91     return nexus.StateFromFeedback() == UNINITIALIZED; | 
|  | 92   } else if (kind == Code::NUMBER_OF_KINDS) { | 
|  | 93     // Code::NUMBER_OF_KINDS indicates a slot that was never even compiled | 
|  | 94     // in full code. | 
|  | 95     return true; | 
|  | 96   } | 
|  | 97 | 
|  | 98   return false; | 
|  | 99 } | 
|  | 100 | 
|  | 101 | 
| 84 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { | 102 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { | 
| 85   Handle<Object> maybe_code = GetInfo(ast_id); | 103   Handle<Object> maybe_code = GetInfo(ast_id); | 
| 86   if (!maybe_code->IsCode()) return false; | 104   if (!maybe_code->IsCode()) return false; | 
| 87   Handle<Code> code = Handle<Code>::cast(maybe_code); | 105   Handle<Code> code = Handle<Code>::cast(maybe_code); | 
| 88   return code->ic_state() == UNINITIALIZED; | 106   return code->ic_state() == UNINITIALIZED; | 
| 89 } | 107 } | 
| 90 | 108 | 
| 91 | 109 | 
| 92 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { | 110 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { | 
| 93   Handle<Object> value = GetInfo(slot); | 111   Handle<Object> value = GetInfo(slot); | 
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 270 | 288 | 
| 271 void TypeFeedbackOracle::PropertyReceiverTypes(TypeFeedbackId id, | 289 void TypeFeedbackOracle::PropertyReceiverTypes(TypeFeedbackId id, | 
| 272                                                Handle<String> name, | 290                                                Handle<String> name, | 
| 273                                                SmallMapList* receiver_types) { | 291                                                SmallMapList* receiver_types) { | 
| 274   receiver_types->Clear(); | 292   receiver_types->Clear(); | 
| 275   Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 293   Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 
| 276   CollectReceiverTypes(id, name, flags, receiver_types); | 294   CollectReceiverTypes(id, name, flags, receiver_types); | 
| 277 } | 295 } | 
| 278 | 296 | 
| 279 | 297 | 
|  | 298 bool TypeFeedbackOracle::HasOnlyStringMaps(SmallMapList* receiver_types) { | 
|  | 299   bool all_strings = receiver_types->length() > 0; | 
|  | 300   for (int i = 0; i < receiver_types->length(); i++) { | 
|  | 301     all_strings &= receiver_types->at(i)->IsStringMap(); | 
|  | 302   } | 
|  | 303   return all_strings; | 
|  | 304 } | 
|  | 305 | 
|  | 306 | 
| 280 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( | 307 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( | 
| 281     TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) { | 308     TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) { | 
| 282   receiver_types->Clear(); | 309   receiver_types->Clear(); | 
| 283   CollectReceiverTypes(id, receiver_types); | 310   CollectReceiverTypes(id, receiver_types); | 
| 284 | 311   *is_string = HasOnlyStringMaps(receiver_types); | 
| 285   // Are all the receiver maps string maps? |  | 
| 286   bool all_strings = receiver_types->length() > 0; |  | 
| 287   for (int i = 0; i < receiver_types->length(); i++) { |  | 
| 288     all_strings &= receiver_types->at(i)->IsStringMap(); |  | 
| 289   } |  | 
| 290   *is_string = all_strings; |  | 
| 291 } | 312 } | 
| 292 | 313 | 
| 293 | 314 | 
|  | 315 void TypeFeedbackOracle::PropertyReceiverTypes(FeedbackVectorICSlot slot, | 
|  | 316                                                Handle<String> name, | 
|  | 317                                                SmallMapList* receiver_types) { | 
|  | 318   receiver_types->Clear(); | 
|  | 319   LoadICNexus nexus(feedback_vector_, slot); | 
|  | 320   Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 
|  | 321   CollectReceiverTypes(&nexus, name, flags, receiver_types); | 
|  | 322 } | 
|  | 323 | 
|  | 324 | 
|  | 325 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( | 
|  | 326     FeedbackVectorICSlot slot, SmallMapList* receiver_types, bool* is_string) { | 
|  | 327   receiver_types->Clear(); | 
|  | 328   KeyedLoadICNexus nexus(feedback_vector_, slot); | 
|  | 329   CollectReceiverTypes<FeedbackNexus>(&nexus, receiver_types); | 
|  | 330   *is_string = HasOnlyStringMaps(receiver_types); | 
|  | 331 } | 
|  | 332 | 
|  | 333 | 
| 294 void TypeFeedbackOracle::AssignmentReceiverTypes( | 334 void TypeFeedbackOracle::AssignmentReceiverTypes( | 
| 295     TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) { | 335     TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) { | 
| 296   receiver_types->Clear(); | 336   receiver_types->Clear(); | 
| 297   Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 337   Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 
| 298   CollectReceiverTypes(id, name, flags, receiver_types); | 338   CollectReceiverTypes(id, name, flags, receiver_types); | 
| 299 } | 339 } | 
| 300 | 340 | 
| 301 | 341 | 
| 302 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | 342 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | 
| 303     TypeFeedbackId id, SmallMapList* receiver_types, | 343     TypeFeedbackId id, SmallMapList* receiver_types, | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 317 | 357 | 
| 318 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 358 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 
| 319                                               Handle<String> name, | 359                                               Handle<String> name, | 
| 320                                               Code::Flags flags, | 360                                               Code::Flags flags, | 
| 321                                               SmallMapList* types) { | 361                                               SmallMapList* types) { | 
| 322   Handle<Object> object = GetInfo(ast_id); | 362   Handle<Object> object = GetInfo(ast_id); | 
| 323   if (object->IsUndefined() || object->IsSmi()) return; | 363   if (object->IsUndefined() || object->IsSmi()) return; | 
| 324 | 364 | 
| 325   DCHECK(object->IsCode()); | 365   DCHECK(object->IsCode()); | 
| 326   Handle<Code> code(Handle<Code>::cast(object)); | 366   Handle<Code> code(Handle<Code>::cast(object)); | 
|  | 367   CollectReceiverTypes<Code>(*code, name, flags, types); | 
|  | 368 } | 
| 327 | 369 | 
|  | 370 | 
|  | 371 template <class T> | 
|  | 372 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, Handle<String> name, | 
|  | 373                                               Code::Flags flags, | 
|  | 374                                               SmallMapList* types) { | 
| 328   if (FLAG_collect_megamorphic_maps_from_stub_cache && | 375   if (FLAG_collect_megamorphic_maps_from_stub_cache && | 
| 329       code->ic_state() == MEGAMORPHIC) { | 376       obj->ic_state() == MEGAMORPHIC) { | 
| 330     types->Reserve(4, zone()); | 377     types->Reserve(4, zone()); | 
| 331     isolate()->stub_cache()->CollectMatchingMaps( | 378     isolate()->stub_cache()->CollectMatchingMaps( | 
| 332         types, name, flags, native_context_, zone()); | 379         types, name, flags, native_context_, zone()); | 
| 333   } else { | 380   } else { | 
| 334     CollectReceiverTypes(ast_id, types); | 381     CollectReceiverTypes<T>(obj, types); | 
| 335   } | 382   } | 
| 336 } | 383 } | 
| 337 | 384 | 
| 338 | 385 | 
| 339 // Check if a map originates from a given native context. We use this | 386 // Check if a map originates from a given native context. We use this | 
| 340 // information to filter out maps from different context to avoid | 387 // information to filter out maps from different context to avoid | 
| 341 // retaining objects from different tabs in Chrome via optimized code. | 388 // retaining objects from different tabs in Chrome via optimized code. | 
| 342 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map, | 389 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map, | 
| 343                                                Context* native_context) { | 390                                                Context* native_context) { | 
| 344   Object* constructor = NULL; | 391   Object* constructor = NULL; | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 368   return function->context()->global_object() != native_context->global_object() | 415   return function->context()->global_object() != native_context->global_object() | 
| 369       && function->context()->global_object() != native_context->builtins(); | 416       && function->context()->global_object() != native_context->builtins(); | 
| 370 } | 417 } | 
| 371 | 418 | 
| 372 | 419 | 
| 373 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 420 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 
| 374                                               SmallMapList* types) { | 421                                               SmallMapList* types) { | 
| 375   Handle<Object> object = GetInfo(ast_id); | 422   Handle<Object> object = GetInfo(ast_id); | 
| 376   if (!object->IsCode()) return; | 423   if (!object->IsCode()) return; | 
| 377   Handle<Code> code = Handle<Code>::cast(object); | 424   Handle<Code> code = Handle<Code>::cast(object); | 
|  | 425   CollectReceiverTypes<Code>(*code, types); | 
|  | 426 } | 
|  | 427 | 
|  | 428 | 
|  | 429 template <class T> | 
|  | 430 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { | 
| 378   MapHandleList maps; | 431   MapHandleList maps; | 
| 379   if (code->ic_state() == MONOMORPHIC) { | 432   if (obj->ic_state() == MONOMORPHIC) { | 
| 380     Map* map = code->FindFirstMap(); | 433     Map* map = obj->FindFirstMap(); | 
| 381     if (map != NULL) maps.Add(handle(map)); | 434     if (map != NULL) maps.Add(handle(map)); | 
| 382   } else if (code->ic_state() == POLYMORPHIC) { | 435   } else if (obj->ic_state() == POLYMORPHIC) { | 
| 383     code->FindAllMaps(&maps); | 436     obj->FindAllMaps(&maps); | 
| 384   } else { | 437   } else { | 
| 385     return; | 438     return; | 
| 386   } | 439   } | 
| 387   types->Reserve(maps.length(), zone()); | 440   types->Reserve(maps.length(), zone()); | 
| 388   for (int i = 0; i < maps.length(); i++) { | 441   for (int i = 0; i < maps.length(); i++) { | 
| 389     Handle<Map> map(maps.at(i)); | 442     Handle<Map> map(maps.at(i)); | 
| 390     if (!CanRetainOtherContext(*map, *native_context_)) { | 443     if (!CanRetainOtherContext(*map, *native_context_)) { | 
| 391       types->AddMapIfMissing(map, zone()); | 444       types->AddMapIfMissing(map, zone()); | 
| 392     } | 445     } | 
| 393   } | 446   } | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 477          UnseededNumberDictionary::kNotFound); | 530          UnseededNumberDictionary::kNotFound); | 
| 478   // Dictionary has been allocated with sufficient size for all elements. | 531   // Dictionary has been allocated with sufficient size for all elements. | 
| 479   DisallowHeapAllocation no_need_to_resize_dictionary; | 532   DisallowHeapAllocation no_need_to_resize_dictionary; | 
| 480   HandleScope scope(isolate()); | 533   HandleScope scope(isolate()); | 
| 481   USE(UnseededNumberDictionary::AtNumberPut( | 534   USE(UnseededNumberDictionary::AtNumberPut( | 
| 482       dictionary_, IdToKey(ast_id), handle(target, isolate()))); | 535       dictionary_, IdToKey(ast_id), handle(target, isolate()))); | 
| 483 } | 536 } | 
| 484 | 537 | 
| 485 | 538 | 
| 486 } }  // namespace v8::internal | 539 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|