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

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

Issue 1020803004: Remove CanRetainOtherContext since embedded objects are now weak. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Less negations Created 5 years, 9 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
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 return Handle<Object>(value, isolate()); 45 return Handle<Object>(value, isolate());
46 } 46 }
47 } 47 }
48 return Handle<Object>::cast(isolate()->factory()->undefined_value()); 48 return Handle<Object>::cast(isolate()->factory()->undefined_value());
49 } 49 }
50 50
51 51
52 Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorSlot slot) { 52 Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorSlot slot) {
53 DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length()); 53 DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length());
54 Object* obj = feedback_vector_->Get(slot); 54 Object* obj = feedback_vector_->Get(slot);
55 if (!obj->IsJSFunction() || 55 return Handle<Object>(obj, isolate());
56 !CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) {
57 DCHECK(!obj->IsMap());
58 return Handle<Object>(obj, isolate());
59 }
60 return Handle<Object>::cast(isolate()->factory()->undefined_value());
61 } 56 }
62 57
63 58
64 Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorICSlot slot) { 59 Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorICSlot slot) {
65 DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length()); 60 DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length());
66 Handle<Object> undefined = 61 Handle<Object> undefined =
67 Handle<Object>::cast(isolate()->factory()->undefined_value()); 62 Handle<Object>::cast(isolate()->factory()->undefined_value());
68 Object* obj = feedback_vector_->Get(slot); 63 Object* obj = feedback_vector_->Get(slot);
69 64
70 // Vector-based ICs do not embed direct pointers to maps, functions. 65 // Vector-based ICs do not embed direct pointers to maps, functions.
71 // Instead a WeakCell is always used. 66 // Instead a WeakCell is always used.
72 if (obj->IsWeakCell()) { 67 if (obj->IsWeakCell()) {
73 WeakCell* cell = WeakCell::cast(obj); 68 WeakCell* cell = WeakCell::cast(obj);
74 if (cell->cleared()) return undefined; 69 if (cell->cleared()) return undefined;
75 obj = cell->value(); 70 obj = cell->value();
76 } 71 }
77 72
78 if ((obj->IsJSFunction() && 73 if (obj->IsJSFunction() || obj->IsAllocationSite() || obj->IsSymbol()) {
79 !CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) ||
80 obj->IsAllocationSite() || obj->IsSymbol()) {
81 return Handle<Object>(obj, isolate()); 74 return Handle<Object>(obj, isolate());
82 } 75 }
83 76
84 return undefined; 77 return undefined;
85 } 78 }
86 79
87 80
88 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { 81 bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
89 Handle<Object> maybe_code = GetInfo(id); 82 Handle<Object> maybe_code = GetInfo(id);
90 if (maybe_code->IsCode()) { 83 if (maybe_code->IsCode()) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 Handle<Object> info = GetInfo(id); 234 Handle<Object> info = GetInfo(id);
242 if (!info->IsCode()) { 235 if (!info->IsCode()) {
243 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. 236 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof.
244 *left_type = *right_type = *combined_type = Type::None(zone()); 237 *left_type = *right_type = *combined_type = Type::None(zone());
245 return; 238 return;
246 } 239 }
247 Handle<Code> code = Handle<Code>::cast(info); 240 Handle<Code> code = Handle<Code>::cast(info);
248 241
249 Handle<Map> map; 242 Handle<Map> map;
250 Map* raw_map = code->FindFirstMap(); 243 Map* raw_map = code->FindFirstMap();
251 if (raw_map != NULL) { 244 if (raw_map != NULL) Map::TryUpdate(handle(raw_map)).ToHandle(&map);
252 if (Map::TryUpdate(handle(raw_map)).ToHandle(&map) &&
253 CanRetainOtherContext(*map, *native_context_)) {
254 map = Handle<Map>::null();
255 }
256 }
257 245
258 if (code->is_compare_ic_stub()) { 246 if (code->is_compare_ic_stub()) {
259 CompareICStub stub(code->stub_key(), isolate()); 247 CompareICStub stub(code->stub_key(), isolate());
260 *left_type = CompareICState::StateToType(zone(), stub.left()); 248 *left_type = CompareICState::StateToType(zone(), stub.left());
261 *right_type = CompareICState::StateToType(zone(), stub.right()); 249 *right_type = CompareICState::StateToType(zone(), stub.right());
262 *combined_type = CompareICState::StateToType(zone(), stub.state(), map); 250 *combined_type = CompareICState::StateToType(zone(), stub.state(), map);
263 } else if (code->is_compare_nil_ic_stub()) { 251 } else if (code->is_compare_nil_ic_stub()) {
264 CompareNilICStub stub(isolate(), code->extra_ic_state()); 252 CompareNilICStub stub(isolate(), code->extra_ic_state());
265 *combined_type = stub.GetType(zone(), map); 253 *combined_type = stub.GetType(zone(), map);
266 *left_type = *right_type = stub.GetInputType(zone(), map); 254 *left_type = *right_type = stub.GetInputType(zone(), map);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 obj->ic_state() == MEGAMORPHIC) { 400 obj->ic_state() == MEGAMORPHIC) {
413 types->Reserve(4, zone()); 401 types->Reserve(4, zone());
414 isolate()->stub_cache()->CollectMatchingMaps( 402 isolate()->stub_cache()->CollectMatchingMaps(
415 types, name, flags, native_context_, zone()); 403 types, name, flags, native_context_, zone());
416 } else { 404 } else {
417 CollectReceiverTypes<T>(obj, types); 405 CollectReceiverTypes<T>(obj, types);
418 } 406 }
419 } 407 }
420 408
421 409
422 // Check if a map originates from a given native context. We use this
423 // information to filter out maps from different context to avoid
424 // retaining objects from different tabs in Chrome via optimized code.
425 bool TypeFeedbackOracle::CanRetainOtherContext(Map* map,
426 Context* native_context) {
427 Object* constructor = NULL;
428 while (!map->prototype()->IsNull()) {
429 constructor = map->GetConstructor();
430 if (!constructor->IsNull()) {
431 // If the constructor is not null or a JSFunction, we have to
432 // conservatively assume that it may retain a native context.
433 if (!constructor->IsJSFunction()) return true;
434 // Check if the constructor directly references a foreign context.
435 if (CanRetainOtherContext(JSFunction::cast(constructor),
436 native_context)) {
437 return true;
438 }
439 }
440 map = HeapObject::cast(map->prototype())->map();
441 }
442 constructor = map->GetConstructor();
443 if (constructor->IsNull()) return false;
444 // If the constructor is not null or a JSFunction, we have to conservatively
445 // assume that it may retain a native context.
446 if (!constructor->IsJSFunction()) return true;
447 JSFunction* function = JSFunction::cast(constructor);
448 return CanRetainOtherContext(function, native_context);
449 }
450
451
452 bool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function,
453 Context* native_context) {
454 return function->context()->global_object() != native_context->global_object()
455 && function->context()->global_object() != native_context->builtins();
456 }
457
458
459 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, 410 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
460 SmallMapList* types) { 411 SmallMapList* types) {
461 Handle<Object> object = GetInfo(ast_id); 412 Handle<Object> object = GetInfo(ast_id);
462 if (!object->IsCode()) return; 413 if (!object->IsCode()) return;
463 Handle<Code> code = Handle<Code>::cast(object); 414 Handle<Code> code = Handle<Code>::cast(object);
464 CollectReceiverTypes<Code>(*code, types); 415 CollectReceiverTypes<Code>(*code, types);
465 } 416 }
466 417
467 418
468 template <class T> 419 template <class T>
469 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { 420 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) {
470 MapHandleList maps; 421 MapHandleList maps;
471 if (obj->ic_state() == MONOMORPHIC) { 422 if (obj->ic_state() == MONOMORPHIC) {
472 Map* map = obj->FindFirstMap(); 423 Map* map = obj->FindFirstMap();
473 if (map != NULL) maps.Add(handle(map)); 424 if (map != NULL) maps.Add(handle(map));
474 } else if (obj->ic_state() == POLYMORPHIC) { 425 } else if (obj->ic_state() == POLYMORPHIC) {
475 obj->FindAllMaps(&maps); 426 obj->FindAllMaps(&maps);
476 } else { 427 } else {
477 return; 428 return;
478 } 429 }
479 types->Reserve(maps.length(), zone()); 430 types->Reserve(maps.length(), zone());
480 for (int i = 0; i < maps.length(); i++) { 431 for (int i = 0; i < maps.length(); i++) {
481 Handle<Map> map(maps.at(i)); 432 Handle<Map> map(maps.at(i));
Erik Corry 2015/03/26 11:20:57 Perhaps you don't need this variable if it's only
482 if (!CanRetainOtherContext(*map, *native_context_)) { 433 if (IsRelevantFeedback(*map, *native_context_)) {
483 types->AddMapIfMissing(map, zone()); 434 types->AddMapIfMissing(maps.at(i), zone());
484 } 435 }
485 } 436 }
486 } 437 }
487 438
488 439
489 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) { 440 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) {
490 Handle<Object> object = GetInfo(id); 441 Handle<Object> object = GetInfo(id);
491 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; 442 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
492 } 443 }
493 444
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 UnseededNumberDictionary::kNotFound); 520 UnseededNumberDictionary::kNotFound);
570 // Dictionary has been allocated with sufficient size for all elements. 521 // Dictionary has been allocated with sufficient size for all elements.
571 DisallowHeapAllocation no_need_to_resize_dictionary; 522 DisallowHeapAllocation no_need_to_resize_dictionary;
572 HandleScope scope(isolate()); 523 HandleScope scope(isolate());
573 USE(UnseededNumberDictionary::AtNumberPut( 524 USE(UnseededNumberDictionary::AtNumberPut(
574 dictionary_, IdToKey(ast_id), handle(target, isolate()))); 525 dictionary_, IdToKey(ast_id), handle(target, isolate())));
575 } 526 }
576 527
577 528
578 } } // namespace v8::internal 529 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698