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

Side by Side Diff: src/type-info.cc

Issue 754303003: Flesh out vector ic state query and set mechanisms. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 6 years 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
« no previous file with comments | « src/type-info.h ('k') | src/typing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/typing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698