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

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

Issue 104793003: Fix polymorphic inlined calls with migrating prototypes (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fixed inefficient recursion Created 7 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 | Annotate | Revision Log
« 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 // 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 int entry = dictionary_->FindEntry(IdToKey(ast_id)); 93 int entry = dictionary_->FindEntry(IdToKey(ast_id));
94 if (entry != UnseededNumberDictionary::kNotFound) { 94 if (entry != UnseededNumberDictionary::kNotFound) {
95 Cell* cell = Cell::cast(dictionary_->ValueAt(entry)); 95 Cell* cell = Cell::cast(dictionary_->ValueAt(entry));
96 return Handle<Cell>(cell, isolate_); 96 return Handle<Cell>(cell, isolate_);
97 } 97 }
98 return Handle<Cell>::null(); 98 return Handle<Cell>::null();
99 } 99 }
100 100
101 101
102 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { 102 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
103 Handle<Object> map_or_code = GetInfo(id); 103 Handle<Object> maybe_code = GetInfo(id);
104 if (map_or_code->IsMap()) return false; 104 if (maybe_code->IsCode()) {
105 if (map_or_code->IsCode()) { 105 Handle<Code> code = Handle<Code>::cast(maybe_code);
106 Handle<Code> code = Handle<Code>::cast(map_or_code);
107 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; 106 return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED;
108 } 107 }
109 return false; 108 return false;
110 } 109 }
111 110
112 111
113 bool TypeFeedbackOracle::LoadIsMonomorphicNormal(TypeFeedbackId id) {
114 Handle<Object> map_or_code = GetInfo(id);
115 if (map_or_code->IsMap()) return true;
116 if (map_or_code->IsCode()) {
117 Handle<Code> code = Handle<Code>::cast(map_or_code);
118 bool preliminary_checks = code->is_keyed_load_stub() &&
119 code->ic_state() == MONOMORPHIC &&
120 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
121 if (!preliminary_checks) return false;
122 Map* map = code->FindFirstMap();
123 if (map == NULL) return false;
124 map = map->CurrentMapForDeprecated();
125 return map != NULL && !CanRetainOtherContext(map, *native_context_);
126 }
127 return false;
128 }
129
130
131 bool TypeFeedbackOracle::LoadIsPreMonomorphic(TypeFeedbackId id) { 112 bool TypeFeedbackOracle::LoadIsPreMonomorphic(TypeFeedbackId id) {
132 Handle<Object> map_or_code = GetInfo(id); 113 Handle<Object> maybe_code = GetInfo(id);
133 if (map_or_code->IsCode()) { 114 if (maybe_code->IsCode()) {
134 Handle<Code> code = Handle<Code>::cast(map_or_code); 115 Handle<Code> code = Handle<Code>::cast(maybe_code);
135 return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC; 116 return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC;
136 } 117 }
137 return false; 118 return false;
138 } 119 }
139 120
140 121
141 bool TypeFeedbackOracle::LoadIsPolymorphic(TypeFeedbackId id) {
142 Handle<Object> map_or_code = GetInfo(id);
143 if (map_or_code->IsCode()) {
144 Handle<Code> code = Handle<Code>::cast(map_or_code);
145 return code->is_keyed_load_stub() && code->ic_state() == POLYMORPHIC;
146 }
147 return false;
148 }
149
150
151 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { 122 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) {
152 Handle<Object> map_or_code = GetInfo(ast_id); 123 Handle<Object> maybe_code = GetInfo(ast_id);
153 if (map_or_code->IsMap()) return false; 124 if (!maybe_code->IsCode()) return false;
154 if (!map_or_code->IsCode()) return false; 125 Handle<Code> code = Handle<Code>::cast(maybe_code);
155 Handle<Code> code = Handle<Code>::cast(map_or_code);
156 return code->ic_state() == UNINITIALIZED; 126 return code->ic_state() == UNINITIALIZED;
157 } 127 }
158 128
159 129
160 bool TypeFeedbackOracle::StoreIsMonomorphicNormal(TypeFeedbackId ast_id) {
161 Handle<Object> map_or_code = GetInfo(ast_id);
162 if (map_or_code->IsMap()) return true;
163 if (map_or_code->IsCode()) {
164 Handle<Code> code = Handle<Code>::cast(map_or_code);
165 bool preliminary_checks =
166 code->is_keyed_store_stub() &&
167 code->ic_state() == MONOMORPHIC &&
168 Code::ExtractTypeFromFlags(code->flags()) == Code::NORMAL;
169 if (!preliminary_checks) return false;
170 Map* map = code->FindFirstMap();
171 if (map == NULL) return false;
172 map = map->CurrentMapForDeprecated();
173 return map != NULL && !CanRetainOtherContext(map, *native_context_);
174 }
175 return false;
176 }
177
178
179 bool TypeFeedbackOracle::StoreIsPreMonomorphic(TypeFeedbackId ast_id) { 130 bool TypeFeedbackOracle::StoreIsPreMonomorphic(TypeFeedbackId ast_id) {
180 Handle<Object> map_or_code = GetInfo(ast_id); 131 Handle<Object> maybe_code = GetInfo(ast_id);
181 if (map_or_code->IsCode()) { 132 if (maybe_code->IsCode()) {
182 Handle<Code> code = Handle<Code>::cast(map_or_code); 133 Handle<Code> code = Handle<Code>::cast(maybe_code);
183 return code->ic_state() == PREMONOMORPHIC; 134 return code->ic_state() == PREMONOMORPHIC;
184 } 135 }
185 return false; 136 return false;
186 } 137 }
187 138
188 139
189 bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) { 140 bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) {
190 Handle<Object> map_or_code = GetInfo(ast_id); 141 Handle<Object> maybe_code = GetInfo(ast_id);
191 if (map_or_code->IsCode()) { 142 if (maybe_code->IsCode()) {
192 Handle<Code> code = Handle<Code>::cast(map_or_code); 143 Handle<Code> code = Handle<Code>::cast(maybe_code);
193 return code->is_keyed_store_stub() && 144 return code->is_keyed_store_stub() &&
194 code->ic_state() == POLYMORPHIC; 145 code->ic_state() == POLYMORPHIC;
195 } 146 }
196 return false; 147 return false;
197 } 148 }
198 149
199 150
200 bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) { 151 bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) {
201 Handle<Object> value = GetInfo(id); 152 Handle<Object> value = GetInfo(id);
202 return value->IsMap() || value->IsAllocationSite() || value->IsJSFunction() || 153 return value->IsAllocationSite() || value->IsJSFunction() || value->IsSmi() ||
203 value->IsSmi() ||
204 (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC); 154 (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC);
205 } 155 }
206 156
207 157
208 bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) { 158 bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) {
209 Handle<Object> value = GetInfo(id); 159 Handle<Object> value = GetInfo(id);
210 Handle<Code> code = Handle<Code>::cast(value); 160 Handle<Code> code = Handle<Code>::cast(value);
211 return KeyedArrayCallStub::IsHoley(code); 161 return KeyedArrayCallStub::IsHoley(code);
212 } 162 }
213 163
214 164
215 bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) { 165 bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) {
216 Handle<Object> info = GetInfo(id); 166 Handle<Object> info = GetInfo(id);
217 return info->IsAllocationSite() || info->IsJSFunction(); 167 return info->IsAllocationSite() || info->IsJSFunction();
218 } 168 }
219 169
220 170
221 bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic(TypeFeedbackId id) {
222 Handle<Object> map_or_code = GetInfo(id);
223 return map_or_code->IsMap();
224 }
225
226
227 byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) { 171 byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) {
228 Handle<Object> value = GetInfo(id); 172 Handle<Object> value = GetInfo(id);
229 return value->IsSmi() && 173 return value->IsSmi() &&
230 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker 174 Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker
231 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN; 175 ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
232 } 176 }
233 177
234 178
235 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(TypeFeedbackId id) {
236 ASSERT(LoadIsMonomorphicNormal(id));
237 Handle<Object> map_or_code = GetInfo(id);
238 if (map_or_code->IsCode()) {
239 Handle<Code> code = Handle<Code>::cast(map_or_code);
240 Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
241 return map == NULL || CanRetainOtherContext(map, *native_context_)
242 ? Handle<Map>::null()
243 : Handle<Map>(map);
244 }
245 return Handle<Map>::cast(map_or_code);
246 }
247
248
249 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(
250 TypeFeedbackId ast_id) {
251 ASSERT(StoreIsMonomorphicNormal(ast_id));
252 Handle<Object> map_or_code = GetInfo(ast_id);
253 if (map_or_code->IsCode()) {
254 Handle<Code> code = Handle<Code>::cast(map_or_code);
255 Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
256 return map == NULL || CanRetainOtherContext(map, *native_context_)
257 ? Handle<Map>::null()
258 : Handle<Map>(map);
259 }
260 return Handle<Map>::cast(map_or_code);
261 }
262
263
264 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode( 179 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
265 TypeFeedbackId ast_id) { 180 TypeFeedbackId ast_id) {
266 Handle<Object> map_or_code = GetInfo(ast_id); 181 Handle<Object> maybe_code = GetInfo(ast_id);
267 if (map_or_code->IsCode()) { 182 if (maybe_code->IsCode()) {
268 Handle<Code> code = Handle<Code>::cast(map_or_code); 183 Handle<Code> code = Handle<Code>::cast(maybe_code);
269 if (code->kind() == Code::KEYED_STORE_IC) { 184 if (code->kind() == Code::KEYED_STORE_IC) {
270 return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()); 185 return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state());
271 } 186 }
272 } 187 }
273 return STANDARD_STORE; 188 return STANDARD_STORE;
274 } 189 }
275 190
276 191
277 void TypeFeedbackOracle::LoadReceiverTypes(TypeFeedbackId id,
278 Handle<String> name,
279 SmallMapList* types) {
280 Code::Flags flags = Code::ComputeFlags(
281 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
282 Code::NORMAL, Code::LOAD_IC);
283 CollectReceiverTypes(id, name, flags, types);
284 }
285
286
287 void TypeFeedbackOracle::StoreReceiverTypes(TypeFeedbackId id,
288 Handle<String> name,
289 SmallMapList* types) {
290 Code::Flags flags = Code::ComputeFlags(
291 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
292 Code::NORMAL, Code::STORE_IC);
293 CollectReceiverTypes(id, name, flags, types);
294 }
295
296
297 void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id, 192 void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id,
298 Handle<String> name, 193 Handle<String> name,
299 int arity, 194 int arity,
300 CallKind call_kind, 195 CallKind call_kind,
301 SmallMapList* types) { 196 SmallMapList* types) {
302 // Note: Currently we do not take string extra ic data into account 197 // Note: Currently we do not take string extra ic data into account
303 // here. 198 // here.
304 ContextualMode contextual_mode = call_kind == CALL_AS_FUNCTION 199 ContextualMode contextual_mode = call_kind == CALL_AS_FUNCTION
305 ? CONTEXTUAL 200 ? CONTEXTUAL
306 : NOT_CONTEXTUAL; 201 : NOT_CONTEXTUAL;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } 236 }
342 } 237 }
343 238
344 239
345 Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell( 240 Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(
346 TypeFeedbackId id) { 241 TypeFeedbackId id) {
347 return GetInfoCell(id); 242 return GetInfoCell(id);
348 } 243 }
349 244
350 245
351 Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(TypeFeedbackId id) {
352 ASSERT(ObjectLiteralStoreIsMonomorphic(id));
353 return Handle<Map>::cast(GetInfo(id));
354 }
355
356
357 bool TypeFeedbackOracle::LoadIsBuiltin( 246 bool TypeFeedbackOracle::LoadIsBuiltin(
358 TypeFeedbackId id, Builtins::Name builtin) { 247 TypeFeedbackId id, Builtins::Name builtin) {
359 return *GetInfo(id) == isolate_->builtins()->builtin(builtin); 248 return *GetInfo(id) == isolate_->builtins()->builtin(builtin);
360 } 249 }
361 250
362 251
363 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) { 252 bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) {
364 Handle<Object> object = GetInfo(id); 253 Handle<Object> object = GetInfo(id);
365 if (!object->IsCode()) return false; 254 if (!object->IsCode()) return false;
366 Handle<Code> code = Handle<Code>::cast(object); 255 Handle<Code> code = Handle<Code>::cast(object);
(...skipping 11 matching lines...) Expand all
378 if (!info->IsCode()) { 267 if (!info->IsCode()) {
379 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. 268 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof.
380 *left_type = *right_type = *combined_type = handle(Type::None(), isolate_); 269 *left_type = *right_type = *combined_type = handle(Type::None(), isolate_);
381 return; 270 return;
382 } 271 }
383 Handle<Code> code = Handle<Code>::cast(info); 272 Handle<Code> code = Handle<Code>::cast(info);
384 273
385 Handle<Map> map; 274 Handle<Map> map;
386 Map* raw_map = code->FindFirstMap(); 275 Map* raw_map = code->FindFirstMap();
387 if (raw_map != NULL) { 276 if (raw_map != NULL) {
388 raw_map = raw_map->CurrentMapForDeprecated(); 277 map = Map::CurrentMapForDeprecated(handle(raw_map));
389 if (raw_map != NULL && !CanRetainOtherContext(raw_map, *native_context_)) { 278 if (!map.is_null() && CanRetainOtherContext(*map, *native_context_)) {
390 map = handle(raw_map, isolate_); 279 map = Handle<Map>::null();
391 } 280 }
392 } 281 }
393 282
394 if (code->is_compare_ic_stub()) { 283 if (code->is_compare_ic_stub()) {
395 int stub_minor_key = code->stub_info(); 284 int stub_minor_key = code->stub_info();
396 CompareIC::StubInfoToType( 285 CompareIC::StubInfoToType(
397 stub_minor_key, left_type, right_type, combined_type, map, isolate()); 286 stub_minor_key, left_type, right_type, combined_type, map, isolate());
398 } else if (code->is_compare_nil_ic_stub()) { 287 } else if (code->is_compare_nil_ic_stub()) {
399 CompareNilICStub stub(code->extended_extra_ic_state()); 288 CompareNilICStub stub(code->extended_extra_ic_state());
400 *combined_type = stub.GetType(isolate_, map); 289 *combined_type = stub.GetType(isolate_, map);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 } 342 }
454 343
455 344
456 void TypeFeedbackOracle::PropertyReceiverTypes( 345 void TypeFeedbackOracle::PropertyReceiverTypes(
457 TypeFeedbackId id, Handle<String> name, 346 TypeFeedbackId id, Handle<String> name,
458 SmallMapList* receiver_types, bool* is_prototype) { 347 SmallMapList* receiver_types, bool* is_prototype) {
459 receiver_types->Clear(); 348 receiver_types->Clear();
460 FunctionPrototypeStub proto_stub(Code::LOAD_IC); 349 FunctionPrototypeStub proto_stub(Code::LOAD_IC);
461 *is_prototype = LoadIsStub(id, &proto_stub); 350 *is_prototype = LoadIsStub(id, &proto_stub);
462 if (!*is_prototype) { 351 if (!*is_prototype) {
463 LoadReceiverTypes(id, name, receiver_types); 352 Code::Flags flags = Code::ComputeFlags(
353 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
354 Code::NORMAL, Code::LOAD_IC);
355 CollectReceiverTypes(id, name, flags, receiver_types);
464 } 356 }
465 } 357 }
466 358
467 359
468 void TypeFeedbackOracle::KeyedPropertyReceiverTypes( 360 void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
469 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) { 361 TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) {
470 receiver_types->Clear(); 362 receiver_types->Clear();
471 *is_string = false; 363 *is_string = false;
472 if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) { 364 if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) {
473 *is_string = true; 365 *is_string = true;
474 } else if (LoadIsMonomorphicNormal(id)) { 366 } else {
475 receiver_types->Add(LoadMonomorphicReceiverType(id), zone()); 367 CollectReceiverTypes(id, receiver_types);
476 } else if (LoadIsPolymorphic(id)) {
477 receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
478 CollectKeyedReceiverTypes(id, receiver_types);
479 } 368 }
480 } 369 }
481 370
482 371
483 void TypeFeedbackOracle::AssignmentReceiverTypes( 372 void TypeFeedbackOracle::AssignmentReceiverTypes(
484 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) { 373 TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) {
485 receiver_types->Clear(); 374 receiver_types->Clear();
486 StoreReceiverTypes(id, name, receiver_types); 375 Code::Flags flags = Code::ComputeFlags(
376 Code::HANDLER, MONOMORPHIC, kNoExtraICState,
377 Code::NORMAL, Code::STORE_IC);
378 CollectReceiverTypes(id, name, flags, receiver_types);
487 } 379 }
488 380
489 381
490 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( 382 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes(
491 TypeFeedbackId id, SmallMapList* receiver_types, 383 TypeFeedbackId id, SmallMapList* receiver_types,
492 KeyedAccessStoreMode* store_mode) { 384 KeyedAccessStoreMode* store_mode) {
493 receiver_types->Clear(); 385 receiver_types->Clear();
494 if (StoreIsMonomorphicNormal(id)) { 386 CollectReceiverTypes(id, receiver_types);
495 // Record receiver type for monomorphic keyed stores.
496 receiver_types->Add(StoreMonomorphicReceiverType(id), zone());
497 } else if (StoreIsKeyedPolymorphic(id)) {
498 receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
499 CollectKeyedReceiverTypes(id, receiver_types);
500 }
501 *store_mode = GetStoreMode(id); 387 *store_mode = GetStoreMode(id);
502 } 388 }
503 389
504 390
505 void TypeFeedbackOracle::CountReceiverTypes( 391 void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id,
506 TypeFeedbackId id, SmallMapList* receiver_types) { 392 SmallMapList* receiver_types) {
507 receiver_types->Clear(); 393 receiver_types->Clear();
508 if (StoreIsMonomorphicNormal(id)) { 394 CollectReceiverTypes(id, receiver_types);
509 // Record receiver type for monomorphic keyed stores.
510 receiver_types->Add(StoreMonomorphicReceiverType(id), zone());
511 } else if (StoreIsKeyedPolymorphic(id)) {
512 receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
513 CollectKeyedReceiverTypes(id, receiver_types);
514 } else {
515 CollectPolymorphicStoreReceiverTypes(id, receiver_types);
516 }
517 } 395 }
518 396
519 397
520 void TypeFeedbackOracle::CollectPolymorphicMaps(Handle<Code> code,
521 SmallMapList* types) {
522 MapHandleList maps;
523 code->FindAllMaps(&maps);
524 types->Reserve(maps.length(), zone());
525 for (int i = 0; i < maps.length(); i++) {
526 Handle<Map> map(maps.at(i));
527 if (!CanRetainOtherContext(*map, *native_context_)) {
528 types->AddMapIfMissing(map, zone());
529 }
530 }
531 }
532
533
534 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, 398 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
535 Handle<String> name, 399 Handle<String> name,
536 Code::Flags flags, 400 Code::Flags flags,
537 SmallMapList* types) { 401 SmallMapList* types) {
538 Handle<Object> object = GetInfo(ast_id); 402 Handle<Object> object = GetInfo(ast_id);
539 if (object->IsUndefined() || object->IsSmi()) return; 403 if (object->IsUndefined() || object->IsSmi()) return;
540 404
541 if (object->IsMap()) { 405 ASSERT(object->IsCode());
542 types->AddMapIfMissing(Handle<Map>::cast(object), zone()); 406 Handle<Code> code(Handle<Code>::cast(object));
543 } else if (Handle<Code>::cast(object)->ic_state() == POLYMORPHIC || 407
544 Handle<Code>::cast(object)->ic_state() == MONOMORPHIC) { 408 if (FLAG_collect_megamorphic_maps_from_stub_cache &&
545 CollectPolymorphicMaps(Handle<Code>::cast(object), types); 409 code->ic_state() == MEGAMORPHIC) {
546 } else if (FLAG_collect_megamorphic_maps_from_stub_cache &&
547 Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) {
548 types->Reserve(4, zone()); 410 types->Reserve(4, zone());
549 ASSERT(object->IsCode()); 411 isolate_->stub_cache()->CollectMatchingMaps(
550 isolate_->stub_cache()->CollectMatchingMaps(types, 412 types, name, flags, native_context_, zone());
551 name, 413 } else {
552 flags, 414 CollectReceiverTypes(ast_id, types);
553 native_context_,
554 zone());
555 } 415 }
556 } 416 }
557 417
558 418
559 // Check if a map originates from a given native context. We use this 419 // Check if a map originates from a given native context. We use this
560 // information to filter out maps from different context to avoid 420 // information to filter out maps from different context to avoid
561 // retaining objects from different tabs in Chrome via optimized code. 421 // retaining objects from different tabs in Chrome via optimized code.
562 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map, 422 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map,
563 Context* native_context) { 423 Context* native_context) {
564 Object* constructor = NULL; 424 Object* constructor = NULL;
(...skipping 18 matching lines...) Expand all
583 } 443 }
584 444
585 445
586 bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function, 446 bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function,
587 Context* native_context) { 447 Context* native_context) {
588 return function->context()->global_object() != native_context->global_object() 448 return function->context()->global_object() != native_context->global_object()
589 && function->context()->global_object() != native_context->builtins(); 449 && function->context()->global_object() != native_context->builtins();
590 } 450 }
591 451
592 452
593 void TypeFeedbackOracle::CollectKeyedReceiverTypes(TypeFeedbackId ast_id, 453 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
594 SmallMapList* types) { 454 SmallMapList* types) {
595 Handle<Object> object = GetInfo(ast_id); 455 Handle<Object> object = GetInfo(ast_id);
596 if (!object->IsCode()) return; 456 if (!object->IsCode()) return;
597 Handle<Code> code = Handle<Code>::cast(object); 457 Handle<Code> code = Handle<Code>::cast(object);
598 if (code->kind() == Code::KEYED_LOAD_IC || 458 MapHandleList maps;
599 code->kind() == Code::KEYED_STORE_IC) { 459 if (code->ic_state() == MONOMORPHIC) {
600 CollectPolymorphicMaps(code, types); 460 Map* map = code->FindFirstMap();
461 if (map != NULL) maps.Add(handle(map));
462 } else if (code->ic_state() == POLYMORPHIC) {
463 code->FindAllMaps(&maps);
464 } else {
465 return;
466 }
467 types->Reserve(maps.length(), zone());
468 for (int i = 0; i < maps.length(); i++) {
469 Handle<Map> map(maps.at(i));
470 if (!CanRetainOtherContext(*map, *native_context_)) {
471 types->AddMapIfMissing(map, zone());
472 }
601 } 473 }
602 } 474 }
603 475
604
605 void TypeFeedbackOracle::CollectPolymorphicStoreReceiverTypes(
606 TypeFeedbackId ast_id,
607 SmallMapList* types) {
608 Handle<Object> object = GetInfo(ast_id);
609 if (!object->IsCode()) return;
610 Handle<Code> code = Handle<Code>::cast(object);
611 if (code->kind() == Code::STORE_IC && code->ic_state() == POLYMORPHIC) {
612 CollectPolymorphicMaps(code, types);
613 }
614 }
615
616 476
617 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) { 477 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) {
618 Handle<Object> object = GetInfo(id); 478 Handle<Object> object = GetInfo(id);
619 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; 479 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
620 } 480 }
621 481
622 482
623 // Things are a bit tricky here: The iterator for the RelocInfos and the infos 483 // Things are a bit tricky here: The iterator for the RelocInfos and the infos
624 // themselves are not GC-safe, so we first get all infos, then we create the 484 // themselves are not GC-safe, so we first get all infos, then we create the
625 // dictionary (possibly triggering GC), and finally we relocate the collected 485 // dictionary (possibly triggering GC), and finally we relocate the collected
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 532
673 533
674 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) { 534 void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
675 for (int i = 0; i < infos->length(); i++) { 535 for (int i = 0; i < infos->length(); i++) {
676 RelocInfo reloc_entry = (*infos)[i]; 536 RelocInfo reloc_entry = (*infos)[i];
677 Address target_address = reloc_entry.target_address(); 537 Address target_address = reloc_entry.target_address();
678 TypeFeedbackId ast_id = 538 TypeFeedbackId ast_id =
679 TypeFeedbackId(static_cast<unsigned>((*infos)[i].data())); 539 TypeFeedbackId(static_cast<unsigned>((*infos)[i].data()));
680 Code* target = Code::GetCodeFromTargetAddress(target_address); 540 Code* target = Code::GetCodeFromTargetAddress(target_address);
681 switch (target->kind()) { 541 switch (target->kind()) {
542 case Code::CALL_IC:
543 if (target->ic_state() == MONOMORPHIC &&
544 target->check_type() != RECEIVER_MAP_CHECK) {
545 SetInfo(ast_id, Smi::FromInt(target->check_type()));
546 break;
547 }
682 case Code::LOAD_IC: 548 case Code::LOAD_IC:
683 case Code::STORE_IC: 549 case Code::STORE_IC:
684 case Code::CALL_IC:
685 if (target->ic_state() == MONOMORPHIC) {
686 if (target->kind() == Code::CALL_IC &&
687 target->check_type() != RECEIVER_MAP_CHECK) {
688 SetInfo(ast_id, Smi::FromInt(target->check_type()));
689 } else {
690 Object* map = target->FindFirstMap();
691 if (map == NULL) {
692 SetInfo(ast_id, static_cast<Object*>(target));
693 } else if (!CanRetainOtherContext(Map::cast(map),
694 *native_context_)) {
695 Map* feedback = Map::cast(map)->CurrentMapForDeprecated();
696 if (feedback != NULL) SetInfo(ast_id, feedback);
697 }
698 }
699 } else {
700 SetInfo(ast_id, target);
701 }
702 break;
703
704 case Code::KEYED_CALL_IC: 550 case Code::KEYED_CALL_IC:
705 case Code::KEYED_LOAD_IC: 551 case Code::KEYED_LOAD_IC:
706 case Code::KEYED_STORE_IC: 552 case Code::KEYED_STORE_IC:
707 case Code::BINARY_OP_IC: 553 case Code::BINARY_OP_IC:
708 case Code::COMPARE_IC: 554 case Code::COMPARE_IC:
709 case Code::TO_BOOLEAN_IC: 555 case Code::TO_BOOLEAN_IC:
710 case Code::COMPARE_NIL_IC: 556 case Code::COMPARE_NIL_IC:
711 SetInfo(ast_id, target); 557 SetInfo(ast_id, target);
712 break; 558 break;
713 559
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 if (info.IsUninitialized()) return Representation::None(); 602 if (info.IsUninitialized()) return Representation::None();
757 if (info.IsSmi()) return Representation::Smi(); 603 if (info.IsSmi()) return Representation::Smi();
758 if (info.IsInteger32()) return Representation::Integer32(); 604 if (info.IsInteger32()) return Representation::Integer32();
759 if (info.IsDouble()) return Representation::Double(); 605 if (info.IsDouble()) return Representation::Double();
760 if (info.IsNumber()) return Representation::Double(); 606 if (info.IsNumber()) return Representation::Double();
761 return Representation::Tagged(); 607 return Representation::Tagged();
762 } 608 }
763 609
764 610
765 } } // namespace v8::internal 611 } } // 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