mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 21:01:50 +00:00
17c33d8d52
This is a reland of 2852408881
Original change's description:
> [vm] Reduce size of Class objects in AOT and PRODUCT modes
>
> This change conditionally removes certain fields from Class objects
> in AOT and PRODUCT modes.
>
> Flutter gallery in release-sizeopt mode:
> Snapshot size -0.47% (arm64), -0.44% (arm)
> Heap size of snapshot objects -4.1% (arm64), -4.3% (arm)
>
> On a large Flutter application compiled in --dwarf-stack-traces mode:
> Heap size of Class objects -26%
> Heap size of all snapshot objects -3.6%
>
> TEST=ci
> Issue: https://github.com/dart-lang/sdk/issues/44020
> Change-Id: I795c625b71558cd2f336f92fc326c36fd339cd4b
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195700
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
TEST=ci
Change-Id: Ib473a959a2c610b7a0e6f4000b2101e5256c6119
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196103
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
130 lines
4.7 KiB
C++
130 lines
4.7 KiB
C++
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_PROGRAM_VISITOR_H_
|
|
#define RUNTIME_VM_PROGRAM_VISITOR_H_
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#include "vm/allocation.h"
|
|
|
|
namespace dart {
|
|
|
|
// Currently, we have three types of abstract visitors that can be extended and
|
|
// used for program walking:
|
|
//
|
|
// * ClassVisitor, a visitor for classes in the program.
|
|
// * FunctionVisitor, a visitor for functions in the program.
|
|
// * CodeVisitor, a visitor for code objects in the program.
|
|
//
|
|
// To find the functions in a program, we must traverse the classes in the
|
|
// program, and similarly for code objects and functions. Thus, each
|
|
// FunctionVisitor is also a ClassVisitor, and each CodeVisitor is also a
|
|
// FunctionVisitor (and thus a ClassVisitor).
|
|
//
|
|
// Only the most specific visitor method is abstract. Derived visitors have a
|
|
// default empty implementation for base visitor methods to limit boilerplate
|
|
// needed when extending. For example, subclasses of CodeVisitor that only do
|
|
// per-Code work do not need to add empty implementations for VisitClass and
|
|
// VisitFunction.
|
|
//
|
|
// There are no guarantees for the order in which objects of a given type will
|
|
// be visited, but each object will be visited only once. In addition, each
|
|
// object is visited before any visitable sub-objects it contains. For example,
|
|
// this means a FunctionVisitor with a VisitClass implementation that drops
|
|
// methods from a class will not visit the dropped methods unless they are also
|
|
// found via another source of function objects.
|
|
//
|
|
// Note that WalkProgram only visits objects in the isolate heap. Deduplicating
|
|
// visitors that want to use VM objects as canonical when possible should
|
|
// instead add the appropriate VM objects first in their constructor.
|
|
|
|
class Class;
|
|
class Code;
|
|
class Function;
|
|
|
|
class CodeVisitor;
|
|
class FunctionVisitor;
|
|
|
|
class ClassVisitor : public ValueObject {
|
|
public:
|
|
virtual ~ClassVisitor() {}
|
|
|
|
virtual bool IsFunctionVisitor() const { return false; }
|
|
const FunctionVisitor* AsFunctionVisitor() const {
|
|
return const_cast<FunctionVisitor*>(
|
|
const_cast<ClassVisitor*>(this)->AsFunctionVisitor());
|
|
}
|
|
FunctionVisitor* AsFunctionVisitor() {
|
|
if (!IsFunctionVisitor()) return nullptr;
|
|
return reinterpret_cast<FunctionVisitor*>(this);
|
|
}
|
|
|
|
virtual bool IsCodeVisitor() const { return false; }
|
|
const CodeVisitor* AsCodeVisitor() const {
|
|
return const_cast<CodeVisitor*>(
|
|
const_cast<ClassVisitor*>(this)->AsCodeVisitor());
|
|
}
|
|
CodeVisitor* AsCodeVisitor() {
|
|
if (!IsCodeVisitor()) return nullptr;
|
|
return reinterpret_cast<CodeVisitor*>(this);
|
|
}
|
|
|
|
virtual void VisitClass(const Class& cls) = 0;
|
|
};
|
|
|
|
class FunctionVisitor : public ClassVisitor {
|
|
public:
|
|
bool IsFunctionVisitor() const { return true; }
|
|
virtual void VisitClass(const Class& cls) {}
|
|
virtual void VisitFunction(const Function& function) = 0;
|
|
};
|
|
|
|
class CodeVisitor : public FunctionVisitor {
|
|
public:
|
|
bool IsCodeVisitor() const { return true; }
|
|
virtual void VisitFunction(const Function& function) {}
|
|
virtual void VisitCode(const Code& code) = 0;
|
|
};
|
|
|
|
class Thread;
|
|
class IsolateGroup;
|
|
|
|
class ProgramVisitor : public AllStatic {
|
|
public:
|
|
// Walks all non-null class, function, and code objects in the program as
|
|
// necessary for the given visitor.
|
|
static void WalkProgram(Zone* zone,
|
|
IsolateGroup* isolate_group,
|
|
ClassVisitor* visitor);
|
|
|
|
static void Dedup(Thread* thread);
|
|
#if defined(DART_PRECOMPILER)
|
|
static void AssignUnits(Thread* thread);
|
|
static uint32_t Hash(Thread* thread);
|
|
#endif
|
|
|
|
private:
|
|
static void BindStaticCalls(Zone* zone, IsolateGroup* isolate_group);
|
|
static void ShareMegamorphicBuckets(Zone* zone, IsolateGroup* isolate_group);
|
|
static void NormalizeAndDedupCompressedStackMaps(Zone* zone,
|
|
IsolateGroup* isolate_group);
|
|
static void DedupPcDescriptors(Zone* zone, IsolateGroup* isolate_group);
|
|
static void DedupDeoptEntries(Zone* zone, IsolateGroup* isolate_group);
|
|
#if defined(DART_PRECOMPILER)
|
|
static void DedupCatchEntryMovesMaps(Zone* zone, IsolateGroup* isolate_group);
|
|
static void DedupUnlinkedCalls(Zone* zone, IsolateGroup* isolate_group);
|
|
static void PruneSubclasses(Zone* zone, IsolateGroup* isolate_group);
|
|
#endif
|
|
static void DedupCodeSourceMaps(Zone* zone, IsolateGroup* isolate_group);
|
|
static void DedupLists(Zone* zone, IsolateGroup* isolate_group);
|
|
static void DedupInstructions(Zone* zone, IsolateGroup* isolate_group);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#endif // RUNTIME_VM_PROGRAM_VISITOR_H_
|