DCHECK(is_done());
code->set_stack_slots(GetStackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
- if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
}
DCHECK(is_done());
code->set_stack_slots(GetStackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
- if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
}
}
-#ifdef VERIFY_HEAP
-NoWeakObjectVerificationScope::NoWeakObjectVerificationScope() {
- Isolate* isolate = Isolate::Current();
- isolate->heap()->no_weak_object_verification_scope_depth_++;
-}
-
-
-NoWeakObjectVerificationScope::~NoWeakObjectVerificationScope() {
- Isolate* isolate = Isolate::Current();
- isolate->heap()->no_weak_object_verification_scope_depth_--;
-}
-#endif
-
-
GCCallbacksScope::GCCallbacksScope(Heap* heap) : heap_(heap) {
heap_->gc_callbacks_depth_++;
}
friend class MarkCompactCollector;
friend class MarkCompactMarkingVisitor;
friend class MapCompact;
-#ifdef VERIFY_HEAP
- friend class NoWeakObjectVerificationScope;
-#endif
friend class Page;
DISALLOW_COPY_AND_ASSIGN(Heap);
};
-#ifdef VERIFY_HEAP
-class NoWeakObjectVerificationScope {
- public:
- inline NoWeakObjectVerificationScope();
- inline ~NoWeakObjectVerificationScope();
-};
-#endif
-
-
class GCCallbacksScope {
public:
explicit inline GCCallbacksScope(Heap* heap);
DCHECK(is_done());
code->set_stack_slots(GetStackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
- if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
if (!info()->IsStub()) {
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
}
-static void AddWeakObjectToCodeDependency(Isolate* isolate,
- Handle<Object> object,
- Handle<Code> code) {
- Heap* heap = isolate->heap();
- heap->EnsureWeakObjectToCodeTable();
- Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
- dep = DependentCode::Insert(dep, DependentCode::kWeakCodeGroup, code);
- heap->AddWeakObjectToCodeDependency(object, dep);
-}
-
-
-void LCodeGenBase::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
- DCHECK(code->is_optimized_code());
- ZoneList<Handle<Map> > maps(1, zone());
- ZoneList<Handle<JSObject> > objects(1, zone());
- ZoneList<Handle<Cell> > cells(1, zone());
- int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
- RelocInfo::ModeMask(RelocInfo::CELL);
- for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
- RelocInfo::Mode mode = it.rinfo()->rmode();
- if (mode == RelocInfo::CELL &&
- code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
- Handle<Cell> cell(it.rinfo()->target_cell());
- cells.Add(cell, zone());
- } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
- code->IsWeakObjectInOptimizedCode(it.rinfo()->target_object())) {
- if (it.rinfo()->target_object()->IsMap()) {
- Handle<Map> map(Map::cast(it.rinfo()->target_object()));
- maps.Add(map, zone());
- } else if (it.rinfo()->target_object()->IsJSObject()) {
- Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
- objects.Add(object, zone());
- } else if (it.rinfo()->target_object()->IsCell()) {
- Handle<Cell> cell(Cell::cast(it.rinfo()->target_object()));
- cells.Add(cell, zone());
- }
- }
- }
- if (FLAG_enable_ool_constant_pool) {
- code->constant_pool()->set_weak_object_state(
- ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE);
- }
-#ifdef VERIFY_HEAP
- // This disables verification of weak embedded objects after full GC.
- // AddDependentCode can cause a GC, which would observe the state where
- // this code is not yet in the depended code lists of the embedded maps.
- NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
-#endif
- for (int i = 0; i < maps.length(); i++) {
- Map::AddDependentCode(maps.at(i), DependentCode::kWeakCodeGroup, code);
- }
- for (int i = 0; i < objects.length(); i++) {
- AddWeakObjectToCodeDependency(isolate(), objects.at(i), code);
- }
- for (int i = 0; i < cells.length(); i++) {
- AddWeakObjectToCodeDependency(isolate(), cells.at(i), code);
- }
-}
-
-
void LCodeGenBase::Abort(BailoutReason reason) {
info()->AbortOptimization(reason);
status_ = ABORTED;
}
+static void AddWeakObjectToCodeDependency(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Code> code) {
+ Heap* heap = isolate->heap();
+ heap->EnsureWeakObjectToCodeTable();
+ Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
+ dep = DependentCode::Insert(dep, DependentCode::kWeakCodeGroup, code);
+ heap->AddWeakObjectToCodeDependency(object, dep);
+}
+
+
+void LChunk::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) const {
+ DCHECK(code->is_optimized_code());
+ ZoneList<Handle<Map> > maps(1, zone());
+ ZoneList<Handle<JSObject> > objects(1, zone());
+ ZoneList<Handle<Cell> > cells(1, zone());
+ int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
+ RelocInfo::ModeMask(RelocInfo::CELL);
+ for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
+ RelocInfo::Mode mode = it.rinfo()->rmode();
+ if (mode == RelocInfo::CELL &&
+ code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
+ Handle<Cell> cell(it.rinfo()->target_cell());
+ cells.Add(cell, zone());
+ } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
+ code->IsWeakObjectInOptimizedCode(it.rinfo()->target_object())) {
+ if (it.rinfo()->target_object()->IsMap()) {
+ Handle<Map> map(Map::cast(it.rinfo()->target_object()));
+ maps.Add(map, zone());
+ } else if (it.rinfo()->target_object()->IsJSObject()) {
+ Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
+ objects.Add(object, zone());
+ } else if (it.rinfo()->target_object()->IsCell()) {
+ Handle<Cell> cell(Cell::cast(it.rinfo()->target_object()));
+ cells.Add(cell, zone());
+ }
+ }
+ }
+ for (int i = 0; i < maps.length(); i++) {
+ Map::AddDependentCode(maps.at(i), DependentCode::kWeakCodeGroup, code);
+ }
+ for (int i = 0; i < objects.length(); i++) {
+ AddWeakObjectToCodeDependency(isolate(), objects.at(i), code);
+ }
+ for (int i = 0; i < cells.length(); i++) {
+ AddWeakObjectToCodeDependency(isolate(), cells.at(i), code);
+ }
+ if (FLAG_enable_ool_constant_pool) {
+ code->constant_pool()->set_weak_object_state(
+ ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE);
+ }
+ code->set_can_have_weak_objects(true);
+}
+
+
void LChunk::CommitDependencies(Handle<Code> code) const {
for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
iend = deprecation_dependencies_.end(); it != iend; ++it) {
}
info_->CommitDependencies(code);
+ if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
}
typedef zone_allocator<Handle<Map> > MapAllocator;
typedef std::set<Handle<Map>, MapLess, MapAllocator> MapSet;
+ void RegisterWeakObjectsInOptimizedCode(Handle<Code> code) const;
void CommitDependencies(Handle<Code> code) const;
CompilationInfo* info_;
DCHECK(is_done());
code->set_stack_slots(GetStackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
- if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
}
DCHECK(is_done());
code->set_stack_slots(GetStackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
- if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
}
}
+inline bool Code::can_have_weak_objects() {
+ DCHECK(kind() == OPTIMIZED_FUNCTION);
+ return CanHaveWeakObjectsField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
+}
+
+
+inline void Code::set_can_have_weak_objects(bool value) {
+ DCHECK(kind() == OPTIMIZED_FUNCTION);
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = CanHaveWeakObjectsField::update(previous, value);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
+}
+
+
bool Code::optimizable() {
DCHECK_EQ(FUNCTION, kind());
return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
inline bool is_turbofanned();
inline void set_is_turbofanned(bool value);
+ // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
+ // embedded objects in code should be treated weakly.
+ inline bool can_have_weak_objects();
+ inline void set_can_have_weak_objects(bool value);
+
// [optimizable]: For FUNCTION kind, tells if it is optimizable.
inline bool optimizable();
inline void set_optimizable(bool value);
void VerifyEmbeddedObjectsInFullCode();
#endif // DEBUG
- inline bool CanContainWeakObjects() { return is_optimized_code(); }
+ inline bool CanContainWeakObjects() {
+ // is_turbofanned() implies !can_have_weak_objects().
+ DCHECK(!is_optimized_code() || !is_turbofanned() ||
+ !can_have_weak_objects());
+ return is_optimized_code() && can_have_weak_objects();
+ }
inline bool IsWeakObject(Object* object) {
- return (is_optimized_code() && !is_turbofanned() &&
- IsWeakObjectInOptimizedCode(object));
+ return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
}
static inline bool IsWeakObjectInOptimizedCode(Object* object);
kStackSlotsFirstBit + kStackSlotsBitCount;
static const int kMarkedForDeoptimizationBit = kHasFunctionCacheBit + 1;
static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
+ static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
- STATIC_ASSERT(kIsTurbofannedBit + 1 <= 32);
+ STATIC_ASSERT(kCanHaveWeakObjects + 1 <= 32);
class StackSlotsField: public BitField<int,
kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
: public BitField<bool, kMarkedForDeoptimizationBit, 1> {}; // NOLINT
class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
}; // NOLINT
+ class CanHaveWeakObjectsField
+ : public BitField<bool, kCanHaveWeakObjects, 1> {}; // NOLINT
// KindSpecificFlags2 layout (ALL)
static const int kIsCrankshaftedBit = 0;
DCHECK(is_done());
code->set_stack_slots(GetStackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
- if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
}
DCHECK(is_done());
code->set_stack_slots(GetStackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
- if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
if (!info()->IsStub()) {
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);