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

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

Issue 7204003: Refactor the way we collect the information for associating type-related infos (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 6 months 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 | Annotate | Revision Log
« no previous file with comments | « src/type-info.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 } else { 55 } else {
56 info = TypeInfo::Unknown(); 56 info = TypeInfo::Unknown();
57 } 57 }
58 return info; 58 return info;
59 } 59 }
60 60
61 61
62 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 62 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
63 Handle<Context> global_context) { 63 Handle<Context> global_context) {
64 global_context_ = global_context; 64 global_context_ = global_context;
65 PopulateMap(code); 65 BuildDictionary(code);
66 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue); 66 ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue);
67 } 67 }
68 68
69 69
70 Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) { 70 Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) {
71 int entry = dictionary_->FindEntry(ast_id); 71 int entry = dictionary_->FindEntry(ast_id);
72 return entry != NumberDictionary::kNotFound 72 return entry != NumberDictionary::kNotFound
73 ? Handle<Object>(dictionary_->ValueAt(entry)) 73 ? Handle<Object>(dictionary_->ValueAt(entry))
74 : Isolate::Current()->factory()->undefined_value(); 74 : Isolate::Current()->factory()->undefined_value();
75 } 75 }
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 RelocInfo* info = it.rinfo(); 431 RelocInfo* info = it.rinfo();
432 Object* object = info->target_object(); 432 Object* object = info->target_object();
433 if (object->IsMap()) { 433 if (object->IsMap()) {
434 types->Add(Handle<Map>(Map::cast(object))); 434 types->Add(Handle<Map>(Map::cast(object)));
435 } 435 }
436 } 436 }
437 } 437 }
438 } 438 }
439 439
440 440
441 // Things are a bit tricky here: The iterator for the RelocInfos and the infos
442 // themselves are not GC-safe, so we first get all infos, then we create the
443 // dictionary (possibly triggering GC), and finally we relocate the collected
444 // infos before we process them.
445 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) {
446 AssertNoAllocation no_allocation;
447 ZoneList<RelocInfo> infos(16);
448 HandleScope scope;
449 GetRelocInfos(code, &infos);
450 CreateDictionary(code, &infos);
451 ProcessRelocInfos(&infos);
452 // Allocate handle in the parent scope.
453 dictionary_ = scope.CloseAndEscape(dictionary_);
454 }
455
456
457 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code,
458 ZoneList<RelocInfo>* infos) {
459 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
460 for (RelocIterator it(*code, mask); !it.done(); it.next()) {
461 infos->Add(*it.rinfo());
462 }
463 }
464
465
466 void TypeFeedbackOracle::CreateDictionary(Handle<Code> code,
467 ZoneList<RelocInfo>* infos) {
468 DisableAssertNoAllocation allocation_allowed;
469 byte* old_start = code->instruction_start();
470 dictionary_ = FACTORY->NewNumberDictionary(infos->length());
471 byte* new_start = code->instruction_start();
472 RelocateRelocInfos(infos, old_start, new_start);
473 }
474
475
476 void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos,
477 byte* old_start,
478 byte* new_start) {
479 for (int i = 0; i < infos->length(); i++) {
480 RelocInfo* info = &(*infos)[i];
481 info->set_pc(new_start + (info->pc() - old_start));
482 }
483 }
484
485
486 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
487 for (int i = 0; i < infos->length(); i++) {
488 unsigned ast_id = static_cast<unsigned>((*infos)[i].data());
489 Code* target = Code::GetCodeFromTargetAddress((*infos)[i].target_address());
490 ProcessTarget(ast_id, target);
491 }
492 }
493
494
495 void TypeFeedbackOracle::ProcessTarget(unsigned ast_id, Code* target) {
496 switch (target->kind()) {
497 case Code::LOAD_IC:
498 case Code::STORE_IC:
499 case Code::CALL_IC:
500 case Code::KEYED_CALL_IC:
501 if (target->ic_state() == MONOMORPHIC) {
502 if (target->kind() == Code::CALL_IC &&
503 target->check_type() != RECEIVER_MAP_CHECK) {
504 SetInfo(ast_id, Smi::FromInt(target->check_type()));
505 } else {
506 Object* map = target->FindFirstMap();
507 SetInfo(ast_id, map == NULL ? static_cast<Object*>(target) : map);
508 }
509 } else if (target->ic_state() == MEGAMORPHIC) {
510 SetInfo(ast_id, target);
511 }
512 break;
513
514 case Code::KEYED_LOAD_IC:
515 case Code::KEYED_STORE_IC:
516 if (target->ic_state() == MONOMORPHIC ||
517 target->ic_state() == MEGAMORPHIC) {
518 SetInfo(ast_id, target);
519 }
520 break;
521
522 case Code::UNARY_OP_IC:
523 case Code::BINARY_OP_IC:
524 case Code::COMPARE_IC:
525 SetInfo(ast_id, target);
526 break;
527
528 default:
529 break;
530 }
531 }
532
533
441 void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) { 534 void TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) {
442 ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound); 535 ASSERT(dictionary_->FindEntry(ast_id) == NumberDictionary::kNotFound);
443 MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target); 536 MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target);
444 USE(maybe_result); 537 USE(maybe_result);
445 #ifdef DEBUG 538 #ifdef DEBUG
446 Object* result = NULL; 539 Object* result = NULL;
447 // Dictionary has been allocated with sufficient size for all elements. 540 // Dictionary has been allocated with sufficient size for all elements.
448 ASSERT(maybe_result->ToObject(&result)); 541 ASSERT(maybe_result->ToObject(&result));
449 ASSERT(*dictionary_ == result); 542 ASSERT(*dictionary_ == result);
450 #endif 543 #endif
451 } 544 }
452 545
453
454 void TypeFeedbackOracle::PopulateMap(Handle<Code> code) {
455 Isolate* isolate = Isolate::Current();
456 HandleScope scope(isolate);
457
458 const int kInitialCapacity = 16;
459 List<int> code_positions(kInitialCapacity);
460 List<unsigned> ast_ids(kInitialCapacity);
461 CollectIds(*code, &code_positions, &ast_ids);
462
463 ASSERT(dictionary_.is_null()); // Only initialize once.
464 dictionary_ = isolate->factory()->NewNumberDictionary(
465 code_positions.length());
466
467 const int length = code_positions.length();
468 ASSERT(ast_ids.length() == length);
469 for (int i = 0; i < length; i++) {
470 AssertNoAllocation no_allocation;
471 RelocInfo info(code->instruction_start() + code_positions[i],
472 RelocInfo::CODE_TARGET, 0);
473 Code* target = Code::GetCodeFromTargetAddress(info.target_address());
474 unsigned id = ast_ids[i];
475 InlineCacheState state = target->ic_state();
476 Code::Kind kind = target->kind();
477
478 if (kind == Code::BINARY_OP_IC ||
479 kind == Code::UNARY_OP_IC ||
480 kind == Code::COMPARE_IC) {
481 SetInfo(id, target);
482 } else if (state == MONOMORPHIC) {
483 if (kind == Code::KEYED_LOAD_IC ||
484 kind == Code::KEYED_STORE_IC) {
485 SetInfo(id, target);
486 } else if (kind != Code::CALL_IC ||
487 target->check_type() == RECEIVER_MAP_CHECK) {
488 Map* map = target->FindFirstMap();
489 if (map == NULL) {
490 SetInfo(id, target);
491 } else {
492 SetInfo(id, map);
493 }
494 } else {
495 ASSERT(target->kind() == Code::CALL_IC);
496 CheckType check = target->check_type();
497 ASSERT(check != RECEIVER_MAP_CHECK);
498 SetInfo(id, Smi::FromInt(check));
499 }
500 } else if (state == MEGAMORPHIC) {
501 SetInfo(id, target);
502 }
503 }
504 // Allocate handle in the parent scope.
505 dictionary_ = scope.CloseAndEscape(dictionary_);
506 }
507
508
509 void TypeFeedbackOracle::CollectIds(Code* code,
510 List<int>* code_positions,
511 List<unsigned>* ast_ids) {
512 AssertNoAllocation no_allocation;
513 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
514 for (RelocIterator it(code, mask); !it.done(); it.next()) {
515 RelocInfo* info = it.rinfo();
516 ASSERT(RelocInfo::IsCodeTarget(info->rmode()));
517 Code* target = Code::GetCodeFromTargetAddress(info->target_address());
518 if (target->is_inline_cache_stub()) {
519 InlineCacheState state = target->ic_state();
520 Code::Kind kind = target->kind();
521 if (kind == Code::BINARY_OP_IC) {
522 if (target->binary_op_type() ==
523 BinaryOpIC::GENERIC) {
524 continue;
525 }
526 } else if (kind == Code::COMPARE_IC) {
527 if (target->compare_state() == CompareIC::GENERIC) continue;
528 } else {
529 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
530 }
531 code_positions->Add(
532 static_cast<int>(info->pc() - code->instruction_start()));
533 ASSERT(ast_ids->length() == 0 ||
534 (*ast_ids)[ast_ids->length()-1] !=
535 static_cast<unsigned>(info->data()));
536 ast_ids->Add(static_cast<unsigned>(info->data()));
537 }
538 }
539 }
540
541 } } // namespace v8::internal 546 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698