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

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

Issue 137403009: Adding a type vector to replace type cells. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: PORTS. Created 6 years, 10 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 29 matching lines...) Expand all
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 45 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
46 Handle<Context> native_context, 46 Handle<Context> native_context,
47 Zone* zone) 47 Zone* zone)
48 : native_context_(native_context), 48 : native_context_(native_context),
49 zone_(zone) { 49 zone_(zone) {
50 Object* raw_info = code->type_feedback_info();
51 if (raw_info->IsTypeFeedbackInfo()) {
52 feedback_vector_ = Handle<FixedArray>(TypeFeedbackInfo::cast(raw_info)->
53 feedback_vector());
54 }
55
50 BuildDictionary(code); 56 BuildDictionary(code);
51 ASSERT(dictionary_->IsDictionary()); 57 ASSERT(dictionary_->IsDictionary());
52 } 58 }
53 59
54 60
55 static uint32_t IdToKey(TypeFeedbackId ast_id) { 61 static uint32_t IdToKey(TypeFeedbackId ast_id) {
56 return static_cast<uint32_t>(ast_id.ToInt()); 62 return static_cast<uint32_t>(ast_id.ToInt());
57 } 63 }
58 64
59 65
60 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) { 66 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
61 int entry = dictionary_->FindEntry(IdToKey(ast_id)); 67 int entry = dictionary_->FindEntry(IdToKey(ast_id));
62 if (entry != UnseededNumberDictionary::kNotFound) { 68 if (entry != UnseededNumberDictionary::kNotFound) {
63 Object* value = dictionary_->ValueAt(entry); 69 Object* value = dictionary_->ValueAt(entry);
64 if (value->IsCell()) { 70 if (value->IsCell()) {
65 Cell* cell = Cell::cast(value); 71 Cell* cell = Cell::cast(value);
66 return Handle<Object>(cell->value(), isolate()); 72 return Handle<Object>(cell->value(), isolate());
67 } else { 73 } else {
68 return Handle<Object>(value, isolate()); 74 return Handle<Object>(value, isolate());
69 } 75 }
70 } 76 }
71 return Handle<Object>::cast(isolate()->factory()->undefined_value()); 77 return Handle<Object>::cast(isolate()->factory()->undefined_value());
72 } 78 }
73 79
74 80
81 Handle<Object> TypeFeedbackOracle::GetInfo(int slot) {
82 ASSERT(slot >= 0 && slot < feedback_vector_->length());
83 Object* obj = feedback_vector_->get(slot);
84 if (obj->IsSmi() || obj->IsAllocationSite() ||
Benedikt Meurer 2014/02/04 08:53:50 Please remove this left over hacks, and use someth
mvstanton 2014/02/04 13:03:27 Thx, I removed the smi and allocationsite check. I
85 (obj->IsJSFunction() &&
86 !CanRetainOtherContext(JSFunction::cast(obj), *native_context_))) {
87 return Handle<Object>(obj, isolate());
88 }
89 return Handle<Object>::cast(isolate()->factory()->undefined_value());
90 }
91
92
75 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { 93 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
76 Handle<Object> maybe_code = GetInfo(id); 94 Handle<Object> maybe_code = GetInfo(id);
77 if (maybe_code->IsCode()) { 95 if (maybe_code->IsCode()) {
78 Handle<Code> code = Handle<Code>::cast(maybe_code); 96 Handle<Code> code = Handle<Code>::cast(maybe_code);
79 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; 97 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED;
80 } 98 }
81 return false; 99 return false;
82 } 100 }
83 101
84 102
(...skipping 29 matching lines...) Expand all
114 Handle<Object> maybe_code = GetInfo(ast_id); 132 Handle<Object> maybe_code = GetInfo(ast_id);
115 if (maybe_code->IsCode()) { 133 if (maybe_code->IsCode()) {
116 Handle<Code> code = Handle<Code>::cast(maybe_code); 134 Handle<Code> code = Handle<Code>::cast(maybe_code);
117 return code->is_keyed_store_stub() && 135 return code->is_keyed_store_stub() &&
118 code->ic_state() == POLYMORPHIC; 136 code->ic_state() == POLYMORPHIC;
119 } 137 }
120 return false; 138 return false;
121 } 139 }
122 140
123 141
142 bool TypeFeedbackOracle::CallIsMonomorphic(int slot) {
143 Handle<Object> value = GetInfo(slot);
144 return value->IsAllocationSite() || value->IsJSFunction();
145 }
146
147
124 bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) { 148 bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) {
125 Handle<Object> value = GetInfo(id); 149 Handle<Object> value = GetInfo(id);
126 return value->IsAllocationSite() || value->IsJSFunction() || value->IsSmi() || 150 return value->IsSmi() ||
127 (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC); 151 (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC);
128 } 152 }
129 153
130 154
131 bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) { 155 bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) {
132 Handle<Object> value = GetInfo(id); 156 Handle<Object> value = GetInfo(id);
133 Handle<Code> code = Handle<Code>::cast(value); 157 Handle<Code> code = Handle<Code>::cast(value);
134 return KeyedArrayCallStub::IsHoley(code); 158 return KeyedArrayCallStub::IsHoley(code);
135 } 159 }
136 160
137 161
138 bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) { 162 bool TypeFeedbackOracle::CallNewIsMonomorphic(int slot) {
139 Handle<Object> info = GetInfo(id); 163 Handle<Object> info = GetInfo(slot);
140 return info->IsAllocationSite() || info->IsJSFunction(); 164 return info->IsAllocationSite() || info->IsJSFunction();
141 } 165 }
142 166
143 167
144 byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) { 168 byte TypeFeedbackOracle::ForInType(int feedback_vector_slot) {
145 Handle<Object> value = GetInfo(id); 169 Handle<Object> value = GetInfo(feedback_vector_slot);
146 return value->IsSmi() && 170 return value->IsSmi() &&
147 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker 171 Smi::cast(*value)->value() == TypeFeedbackInfo::kForInFastCaseMarker
148 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN; 172 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
149 } 173 }
150 174
151 175
152 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode( 176 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
153 TypeFeedbackId ast_id) { 177 TypeFeedbackId ast_id) {
154 Handle<Object> maybe_code = GetInfo(ast_id); 178 Handle<Object> maybe_code = GetInfo(ast_id);
155 if (maybe_code->IsCode()) { 179 if (maybe_code->IsCode()) {
156 Handle<Code> code = Handle<Code>::cast(maybe_code); 180 Handle<Code> code = Handle<Code>::cast(maybe_code);
157 if (code->kind() == Code::KEYED_STORE_IC) { 181 if (code->kind() == Code::KEYED_STORE_IC) {
(...skipping 16 matching lines...) Expand all
174 198
175 CheckType TypeFeedbackOracle::GetCallCheckType(TypeFeedbackId id) { 199 CheckType TypeFeedbackOracle::GetCallCheckType(TypeFeedbackId id) {
176 Handle<Object> value = GetInfo(id); 200 Handle<Object> value = GetInfo(id);
177 if (!value->IsSmi()) return RECEIVER_MAP_CHECK; 201 if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
178 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); 202 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
179 ASSERT(check != RECEIVER_MAP_CHECK); 203 ASSERT(check != RECEIVER_MAP_CHECK);
180 return check; 204 return check;
181 } 205 }
182 206
183 207
184 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(TypeFeedbackId id) { 208 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(int slot) {
185 Handle<Object> info = GetInfo(id); 209 Handle<Object> info = GetInfo(slot);
186 if (info->IsAllocationSite()) { 210 if (info->IsAllocationSite()) {
187 return Handle<JSFunction>(isolate()->global_context()->array_function()); 211 return Handle<JSFunction>(isolate()->global_context()->array_function());
188 } else { 212 } else {
189 return Handle<JSFunction>::cast(info); 213 return Handle<JSFunction>::cast(info);
190 } 214 }
191 } 215 }
192 216
193 217
194 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(TypeFeedbackId id) { 218 Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(int slot) {
195 Handle<Object> info = GetInfo(id); 219 Handle<Object> info = GetInfo(slot);
196 if (info->IsAllocationSite()) { 220 if (info->IsAllocationSite()) {
197 return Handle<JSFunction>(isolate()->global_context()->array_function()); 221 return Handle<JSFunction>(isolate()->global_context()->array_function());
198 } else { 222 } else {
199 return Handle<JSFunction>::cast(info); 223 return Handle<JSFunction>::cast(info);
200 } 224 }
201 } 225 }
202 226
203 227
204 Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite( 228 Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(int slot) {
205 TypeFeedbackId id) { 229 Handle<Object> info = GetInfo(slot);
206 Handle<Object> info = GetInfo(id);
207 if (info->IsAllocationSite()) { 230 if (info->IsAllocationSite()) {
208 return Handle<AllocationSite>::cast(info); 231 return Handle<AllocationSite>::cast(info);
209 } 232 }
210 return Handle<AllocationSite>::null(); 233 return Handle<AllocationSite>::null();
211 } 234 }
212 235
213 236
214 bool TypeFeedbackOracle::LoadIsBuiltin( 237 bool TypeFeedbackOracle::LoadIsBuiltin(
215 TypeFeedbackId id, Builtins::Name builtin) { 238 TypeFeedbackId id, Builtins::Name builtin) {
216 return *GetInfo(id) == isolate()->builtins()->builtin(builtin); 239 return *GetInfo(id) == isolate()->builtins()->builtin(builtin);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 // themselves are not GC-safe, so we first get all infos, then we create the 472 // themselves are not GC-safe, so we first get all infos, then we create the
450 // dictionary (possibly triggering GC), and finally we relocate the collected 473 // dictionary (possibly triggering GC), and finally we relocate the collected
451 // infos before we process them. 474 // infos before we process them.
452 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { 475 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) {
453 DisallowHeapAllocation no_allocation; 476 DisallowHeapAllocation no_allocation;
454 ZoneList<RelocInfo> infos(16, zone()); 477 ZoneList<RelocInfo> infos(16, zone());
455 HandleScope scope(isolate()); 478 HandleScope scope(isolate());
456 GetRelocInfos(code, &infos); 479 GetRelocInfos(code, &infos);
457 CreateDictionary(code, &infos); 480 CreateDictionary(code, &infos);
458 ProcessRelocInfos(&infos); 481 ProcessRelocInfos(&infos);
459 ProcessTypeFeedbackCells(code);
460 // Allocate handle in the parent scope. 482 // Allocate handle in the parent scope.
461 dictionary_ = scope.CloseAndEscape(dictionary_); 483 dictionary_ = scope.CloseAndEscape(dictionary_);
462 } 484 }
463 485
464 486
465 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, 487 void TypeFeedbackOracle::GetRelocInfos(Handle<Code> code,
466 ZoneList<RelocInfo>* infos) { 488 ZoneList<RelocInfo>* infos) {
467 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); 489 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
468 for (RelocIterator it(*code, mask); !it.done(); it.next()) { 490 for (RelocIterator it(*code, mask); !it.done(); it.next()) {
469 infos->Add(*it.rinfo(), zone()); 491 infos->Add(*it.rinfo(), zone());
470 } 492 }
471 } 493 }
472 494
473 495
474 void TypeFeedbackOracle::CreateDictionary(Handle<Code> code, 496 void TypeFeedbackOracle::CreateDictionary(Handle<Code> code,
475 ZoneList<RelocInfo>* infos) { 497 ZoneList<RelocInfo>* infos) {
476 AllowHeapAllocation allocation_allowed; 498 AllowHeapAllocation allocation_allowed;
477 int cell_count = code->type_feedback_info()->IsTypeFeedbackInfo()
478 ? TypeFeedbackInfo::cast(code->type_feedback_info())->
479 type_feedback_cells()->CellCount()
480 : 0;
481 int length = infos->length() + cell_count;
482 byte* old_start = code->instruction_start(); 499 byte* old_start = code->instruction_start();
483 dictionary_ = isolate()->factory()->NewUnseededNumberDictionary(length); 500 dictionary_ =
501 isolate()->factory()->NewUnseededNumberDictionary(infos->length());
484 byte* new_start = code->instruction_start(); 502 byte* new_start = code->instruction_start();
485 RelocateRelocInfos(infos, old_start, new_start); 503 RelocateRelocInfos(infos, old_start, new_start);
486 } 504 }
487 505
488 506
489 void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos, 507 void TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos,
490 byte* old_start, 508 byte* old_start,
491 byte* new_start) { 509 byte* new_start) {
492 for (int i = 0; i < infos->length(); i++) { 510 for (int i = 0; i < infos->length(); i++) {
493 RelocInfo* info = &(*infos)[i]; 511 RelocInfo* info = &(*infos)[i];
(...skipping 28 matching lines...) Expand all
522 SetInfo(ast_id, target); 540 SetInfo(ast_id, target);
523 break; 541 break;
524 542
525 default: 543 default:
526 break; 544 break;
527 } 545 }
528 } 546 }
529 } 547 }
530 548
531 549
532 void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) {
533 Object* raw_info = code->type_feedback_info();
534 if (!raw_info->IsTypeFeedbackInfo()) return;
535 Handle<TypeFeedbackCells> cache(
536 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells());
537 for (int i = 0; i < cache->CellCount(); i++) {
538 TypeFeedbackId ast_id = cache->AstId(i);
539 Cell* cell = cache->GetCell(i);
540 Object* value = cell->value();
541 if (value->IsSmi() ||
542 value->IsAllocationSite() ||
543 (value->IsJSFunction() &&
544 !CanRetainOtherContext(JSFunction::cast(value),
545 *native_context_))) {
546 SetInfo(ast_id, cell);
547 }
548 }
549 }
550
551
552 void TypeFeedbackOracle::SetInfo(TypeFeedbackId ast_id, Object* target) { 550 void TypeFeedbackOracle::SetInfo(TypeFeedbackId ast_id, Object* target) {
553 ASSERT(dictionary_->FindEntry(IdToKey(ast_id)) == 551 ASSERT(dictionary_->FindEntry(IdToKey(ast_id)) ==
554 UnseededNumberDictionary::kNotFound); 552 UnseededNumberDictionary::kNotFound);
555 MaybeObject* maybe_result = dictionary_->AtNumberPut(IdToKey(ast_id), target); 553 MaybeObject* maybe_result = dictionary_->AtNumberPut(IdToKey(ast_id), target);
556 USE(maybe_result); 554 USE(maybe_result);
557 #ifdef DEBUG 555 #ifdef DEBUG
558 Object* result = NULL; 556 Object* result = NULL;
559 // Dictionary has been allocated with sufficient size for all elements. 557 // Dictionary has been allocated with sufficient size for all elements.
560 ASSERT(maybe_result->ToObject(&result)); 558 ASSERT(maybe_result->ToObject(&result));
561 ASSERT(*dictionary_ == result); 559 ASSERT(*dictionary_ == result);
562 #endif 560 #endif
563 } 561 }
564 562
565 563
566 } } // namespace v8::internal 564 } } // namespace v8::internal
OLDNEW
« src/feedback_slots.h ('K') | « src/type-info.h ('k') | src/typing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698