Commit 84a88a1b authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Port Crankshaft's weak objects mechanism to TurboFan.

Use the same mechanism that is already available for Crankshaft to not
leak all kinds of things in TurboFan generated code. Long-term we will
support weakness in a better way, but for now, just use the
infrastructure that is already in place to avoid memory leaks via
TurboFan generated code.

R=jarin@chromium.org, ulan@chromium.org

Review URL: https://codereview.chromium.org/1555743003

Cr-Commit-Position: refs/heads/master@{#33073}
parent cb21144b
......@@ -544,6 +544,61 @@ OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() {
}
namespace {
void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object,
Handle<Code> code) {
Handle<WeakCell> cell = Code::WeakCellFor(code);
Heap* heap = isolate->heap();
Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
dep = DependentCode::InsertWeakCode(dep, DependentCode::kWeakCodeGroup, cell);
heap->AddWeakObjectToCodeDependency(object, dep);
}
void RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
// TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
Isolate* const isolate = code->GetIsolate();
DCHECK(code->is_optimized_code());
std::vector<Handle<Map>> maps;
std::vector<Handle<HeapObject>> objects;
{
DisallowHeapAllocation no_gc;
int const 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())) {
objects.push_back(handle(it.rinfo()->target_cell(), isolate));
} else if (mode == RelocInfo::EMBEDDED_OBJECT &&
code->IsWeakObjectInOptimizedCode(
it.rinfo()->target_object())) {
Handle<HeapObject> object(HeapObject::cast(it.rinfo()->target_object()),
isolate);
if (object->IsMap()) {
maps.push_back(Handle<Map>::cast(object));
} else {
objects.push_back(object);
}
}
}
}
for (Handle<Map> map : maps) {
if (map->dependent_code()->IsEmpty(DependentCode::kWeakCodeGroup)) {
isolate->heap()->AddRetainedMap(map);
}
Map::AddDependentCode(map, DependentCode::kWeakCodeGroup, code);
}
for (Handle<HeapObject> object : objects) {
AddWeakObjectToCodeDependency(isolate, object, code);
}
code->set_can_have_weak_objects(true);
}
} // namespace
OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() {
DCHECK(last_status() == SUCCEEDED);
// TODO(turbofan): Currently everything is done in the first phase.
......@@ -552,6 +607,7 @@ OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() {
if (info()->is_deoptimization_enabled()) {
info()->parse_info()->context()->native_context()->AddOptimizedCode(
*info()->code());
RegisterWeakObjectsInOptimizedCode(info()->code());
}
RecordOptimizationStats();
return last_status();
......@@ -576,6 +632,7 @@ OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() {
}
return SetLastStatus(BAILED_OUT);
}
RegisterWeakObjectsInOptimizedCode(optimized_code);
info()->SetCode(optimized_code);
}
RecordOptimizationStats();
......
......@@ -406,53 +406,6 @@ Representation LChunk::LookupLiteralRepresentation(
}
static void AddWeakObjectToCodeDependency(Isolate* isolate,
Handle<HeapObject> object,
Handle<Code> code) {
Handle<WeakCell> cell = Code::WeakCellFor(code);
Heap* heap = isolate->heap();
Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
dep = DependentCode::InsertWeakCode(dep, DependentCode::kWeakCodeGroup, cell);
heap->AddWeakObjectToCodeDependency(object, dep);
}
void LChunk::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) const {
DCHECK(code->is_optimized_code());
ZoneList<Handle<Map> > maps(1, zone());
ZoneList<Handle<HeapObject> > objects(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())) {
objects.Add(Handle<HeapObject>(it.rinfo()->target_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 {
Handle<HeapObject> object(
HeapObject::cast(it.rinfo()->target_object()));
objects.Add(object, zone());
}
}
}
for (int i = 0; i < maps.length(); i++) {
if (maps.at(i)->dependent_code()->IsEmpty(DependentCode::kWeakCodeGroup)) {
isolate()->heap()->AddRetainedMap(maps.at(i));
}
Map::AddDependentCode(maps.at(i), DependentCode::kWeakCodeGroup, code);
}
for (int i = 0; i < objects.length(); i++) {
AddWeakObjectToCodeDependency(isolate(), objects.at(i), code);
}
code->set_can_have_weak_objects(true);
}
void LChunk::CommitDependencies(Handle<Code> code) const {
if (!code->is_optimized_code()) return;
HandleScope scope(isolate());
......@@ -470,7 +423,6 @@ void LChunk::CommitDependencies(Handle<Code> code) const {
}
info_->dependencies()->Commit(code);
RegisterWeakObjectsInOptimizedCode(code);
}
......
......@@ -690,7 +690,6 @@ class LChunk : public ZoneObject {
int spill_slot_count_;
private:
void RegisterWeakObjectsInOptimizedCode(Handle<Code> code) const;
void CommitDependencies(Handle<Code> code) const;
CompilationInfo* info_;
......
......@@ -5238,8 +5238,6 @@ Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
bool Code::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();
}
......
......@@ -121,10 +121,13 @@
# optimized and hence scripts don't "return" the correct value. Fix this.
'test-compiler/CompileFunctionInContext*': [PASS, NO_VARIANTS],
# TODO(bmeurer): TurboFan embeds strong references to all kinds of objects
# via deoptimization data (Crankshaft also does this, but lack proper test
# coverage).
'test-heap/ObjectsInOptimizedCodeAreWeak': [PASS, NO_VARIANTS],
# TurboFan doesn't support allocation sites currently.
'test-heap/CellsInOptimizedCodeAreWeak': [PASS, NO_VARIANTS],
'test-heap/EnsureAllocationSiteDependentCodesProcessed': [PASS, NO_VARIANTS],
'test-heap/ObjectsInOptimizedCodeAreWeak': [PASS, NO_VARIANTS],
'test-heap/OptimizedPretenuringAllocationFolding': [PASS, NO_VARIANTS],
'test-heap/OptimizedPretenuringdoubleArrayLiterals': [PASS, NO_VARIANTS],
'test-heap/OptimizedPretenuringDoubleArrayProperties': [PASS, NO_VARIANTS],
......
......@@ -4766,17 +4766,19 @@ TEST(CellsInOptimizedCodeAreWeak) {
LocalContext context;
HandleScope scope(heap->isolate());
CompileRun("bar = (function() {"
" function bar() {"
" return foo(1);"
" };"
" var foo = function(x) { with (x) { return 1 + x; } };"
" bar(foo);"
" bar(foo);"
" bar(foo);"
" %OptimizeFunctionOnNextCall(bar);"
" bar(foo);"
" return bar;})();");
CompileRun(
"bar = (function() {"
" function bar() {"
" return foo(1);"
" };"
" var foo = function(x) { with (x) { return 1 + x; } };"
" %NeverOptimizeFunction(foo);"
" bar(foo);"
" bar(foo);"
" bar(foo);"
" %OptimizeFunctionOnNextCall(bar);"
" bar(foo);"
" return bar;})();");
Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CcTest::global()
......@@ -4809,15 +4811,17 @@ TEST(ObjectsInOptimizedCodeAreWeak) {
LocalContext context;
HandleScope scope(heap->isolate());
CompileRun("function bar() {"
" return foo(1);"
"};"
"function foo(x) { with (x) { return 1 + x; } };"
"bar();"
"bar();"
"bar();"
"%OptimizeFunctionOnNextCall(bar);"
"bar();");
CompileRun(
"function bar() {"
" return foo(1);"
"};"
"function foo(x) { with (x) { return 1 + x; } };"
"%NeverOptimizeFunction(foo);"
"bar();"
"bar();"
"bar();"
"%OptimizeFunctionOnNextCall(bar);"
"bar();");
Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CcTest::global()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment