Revert "[vm] Streamline Zones."
This reverts commitb5922e6db4. Reason for revert: vm/cc/AllocateZone fails on Mac Original change's description: > [vm] Streamline Zones. > > - Don't put a HANDLESCOPE right after a StackZone, as there's no state worth restoring > - Remove remaining zone bookkeeping dead sincee3a9d70591. > - Remove unnecessary resetting of handle blocks before zone deletion. > - Shrink initial chunk size to make Zone's overall size fit in a faster malloc size class. > > TEST=ci > Change-Id: I920e12f5af93aa71fb876435764c60df485215f9 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212261 > Reviewed-by: Siva Annamalai <asiva@google.com> > Commit-Queue: Ryan Macnak <rmacnak@google.com> TBR=rmacnak@google.com,asiva@google.com Change-Id: Id23dcebb781791616e48e54d2dcd7e58159178bc No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/215943 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
bfbf75a1f6
commit
472e2bce17
@@ -48,6 +48,7 @@ BENCHMARK(CorelibCompileAll) {
|
||||
bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Timer timer;
|
||||
timer.Start();
|
||||
const Error& error =
|
||||
@@ -412,6 +413,7 @@ BENCHMARK_SIZE(CoreSnapshotSize) {
|
||||
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
Api::CheckAndFinalizePendingClasses(thread);
|
||||
|
||||
@@ -449,6 +451,7 @@ BENCHMARK_SIZE(StandaloneSnapshotSize) {
|
||||
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
Api::CheckAndFinalizePendingClasses(thread);
|
||||
|
||||
@@ -493,6 +496,7 @@ BENCHMARK(EnterExitIsolate) {
|
||||
{
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Api::CheckAndFinalizePendingClasses(thread);
|
||||
}
|
||||
Dart_Isolate isolate = Dart_CurrentIsolate();
|
||||
@@ -510,6 +514,7 @@ BENCHMARK(EnterExitIsolate) {
|
||||
BENCHMARK(SerializeNull) {
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
const Object& null_object = Object::Handle();
|
||||
const intptr_t kLoopCount = 1000000;
|
||||
Timer timer;
|
||||
@@ -531,6 +536,7 @@ BENCHMARK(SerializeNull) {
|
||||
BENCHMARK(SerializeSmi) {
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
const Integer& smi_object = Integer::Handle(Smi::New(42));
|
||||
const intptr_t kLoopCount = 1000000;
|
||||
Timer timer;
|
||||
@@ -552,6 +558,7 @@ BENCHMARK(SerializeSmi) {
|
||||
BENCHMARK(SimpleMessage) {
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
const Array& array_object = Array::Handle(Array::New(2));
|
||||
array_object.SetAt(0, Integer::Handle(Smi::New(42)));
|
||||
array_object.SetAt(1, Object::Handle());
|
||||
@@ -585,6 +592,7 @@ BENCHMARK(LargeMap) {
|
||||
EXPECT_VALID(h_result);
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Instance& map = Instance::Handle();
|
||||
map ^= Api::UnwrapHandle(h_result);
|
||||
const intptr_t kLoopCount = 100;
|
||||
|
||||
@@ -1731,6 +1731,7 @@ void ClassFinalizer::ClearAllCode(bool including_nonchanging_cids) {
|
||||
auto const isolate_group = thread->isolate_group();
|
||||
SafepointWriteRwLocker ml(thread, isolate_group->program_lock());
|
||||
StackZone stack_zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
auto const zone = thread->zone();
|
||||
|
||||
class ClearCodeVisitor : public FunctionVisitor {
|
||||
|
||||
@@ -3009,6 +3009,7 @@ void Precompiler::FinalizeAllClasses() {
|
||||
// otherwise unreachable constants of dropped classes, which would
|
||||
// cause assertion failures during GC after classes are dropped.
|
||||
StackZone stack_zone(thread());
|
||||
HANDLESCOPE(thread());
|
||||
|
||||
error_ = Library::FinalizeAllClasses();
|
||||
if (!error_.IsNull()) {
|
||||
|
||||
@@ -1133,6 +1133,7 @@ void BackgroundCompiler::Run() {
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone stack_zone(thread);
|
||||
Zone* zone = stack_zone.GetZone();
|
||||
HANDLESCOPE(thread);
|
||||
Function& function = Function::Handle(zone);
|
||||
{
|
||||
SafepointMonitorLocker ml(&queue_monitor_);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1301,6 +1301,7 @@ static Dart_Isolate CreateIsolate(IsolateGroup* group,
|
||||
bool success = false;
|
||||
{
|
||||
StackZone zone(T);
|
||||
HANDLESCOPE(T);
|
||||
// We enter an API scope here as InitializeIsolate could compile some
|
||||
// bootstrap library files which call out to a tag handler that may create
|
||||
// Api Handles when an error is encountered.
|
||||
@@ -2052,6 +2053,7 @@ DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal,
|
||||
auto thread = Thread::Current();
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
if (on_error_port != ILLEGAL_PORT) {
|
||||
const auto& port =
|
||||
|
||||
@@ -3128,6 +3128,7 @@ VM_UNIT_TEST_CASE(DartAPI_PersistentHandles) {
|
||||
{
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
for (int i = 0; i < 500; i++) {
|
||||
String& str = String::Handle();
|
||||
str ^= PersistentHandle::Cast(handles[i])->ptr();
|
||||
@@ -4550,6 +4551,7 @@ VM_UNIT_TEST_CASE(DartAPI_LocalHandles) {
|
||||
{
|
||||
TransitionNativeToVM transition1(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Smi& val = Smi::Handle();
|
||||
TransitionVMToNative transition2(thread);
|
||||
|
||||
|
||||
@@ -14,4 +14,6 @@
|
||||
|
||||
namespace dart {
|
||||
|
||||
RelaxedAtomic<intptr_t> ApiNativeScope::current_memory_usage_ = 0;
|
||||
|
||||
} // namespace dart
|
||||
|
||||
@@ -110,7 +110,7 @@ class ApiZone {
|
||||
if ((thread != NULL) && (thread->zone() == &zone_)) {
|
||||
thread->set_zone(zone_.previous_);
|
||||
}
|
||||
zone_.Reset();
|
||||
zone_.DeleteAll();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -656,11 +656,18 @@ class ApiNativeScope {
|
||||
ASSERT(Current() == NULL);
|
||||
OSThread::SetThreadLocal(Api::api_native_key_,
|
||||
reinterpret_cast<uword>(this));
|
||||
// We manually increment the memory usage counter since there is memory
|
||||
// initially allocated within the zone on creation.
|
||||
IncrementNativeScopeMemoryCapacity(zone_.GetZone()->CapacityInBytes());
|
||||
}
|
||||
|
||||
~ApiNativeScope() {
|
||||
ASSERT(Current() == this);
|
||||
OSThread::SetThreadLocal(Api::api_native_key_, 0);
|
||||
// We must also manually decrement the memory usage counter since the native
|
||||
// is still holding it's initial memory and ~Zone() won't be able to
|
||||
// determine which memory usage counter to decrement.
|
||||
DecrementNativeScopeMemoryCapacity(zone_.GetZone()->CapacityInBytes());
|
||||
}
|
||||
|
||||
static inline ApiNativeScope* Current() {
|
||||
@@ -668,6 +675,16 @@ class ApiNativeScope {
|
||||
OSThread::GetThreadLocal(Api::api_native_key_));
|
||||
}
|
||||
|
||||
static uintptr_t current_memory_usage() { return current_memory_usage_; }
|
||||
|
||||
static void IncrementNativeScopeMemoryCapacity(intptr_t size) {
|
||||
current_memory_usage_.fetch_add(size);
|
||||
}
|
||||
|
||||
static void DecrementNativeScopeMemoryCapacity(intptr_t size) {
|
||||
current_memory_usage_.fetch_sub(size);
|
||||
}
|
||||
|
||||
Zone* zone() {
|
||||
Zone* result = zone_.GetZone();
|
||||
ASSERT(result->handles()->CountScopedHandles() == 0);
|
||||
@@ -676,6 +693,9 @@ class ApiNativeScope {
|
||||
}
|
||||
|
||||
private:
|
||||
// The current total memory usage within ApiNativeScopes.
|
||||
static RelaxedAtomic<intptr_t> current_memory_usage_;
|
||||
|
||||
ApiZone zone_;
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,16 @@ namespace dart {
|
||||
|
||||
DEFINE_FLAG(bool, verify_handles, false, "Verify handles.");
|
||||
|
||||
VMHandles::~VMHandles() {
|
||||
if (FLAG_trace_handles) {
|
||||
OS::PrintErr("*** Handle Counts for 0x(%" Px "):Zone = %d,Scoped = %d\n",
|
||||
reinterpret_cast<intptr_t>(this), CountZoneHandles(),
|
||||
CountScopedHandles());
|
||||
OS::PrintErr("*** Deleting VM handle block 0x%" Px "\n",
|
||||
reinterpret_cast<intptr_t>(this));
|
||||
}
|
||||
}
|
||||
|
||||
void VMHandles::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
||||
return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk,
|
||||
kOffsetOfRawPtr>::VisitObjectPointers(visitor);
|
||||
|
||||
+5
-36
@@ -107,24 +107,6 @@ class Handles {
|
||||
return true;
|
||||
}
|
||||
|
||||
intptr_t ZoneHandlesCapacityInBytes() const {
|
||||
intptr_t capacity = 0;
|
||||
for (HandlesBlock* block = zone_blocks_; block != nullptr;
|
||||
block = block->next_block()) {
|
||||
capacity += sizeof(*block);
|
||||
}
|
||||
return capacity;
|
||||
}
|
||||
|
||||
intptr_t ScopedHandlesCapacityInBytes() const {
|
||||
intptr_t capacity = 0;
|
||||
for (HandlesBlock* block = scoped_blocks_; block != nullptr;
|
||||
block = block->next_block()) {
|
||||
capacity += sizeof(*block);
|
||||
}
|
||||
return capacity;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Returns a count of active handles (used for testing purposes).
|
||||
int CountScopedHandles() const;
|
||||
@@ -144,7 +126,7 @@ class Handles {
|
||||
class HandlesBlock : public MallocAllocated {
|
||||
public:
|
||||
explicit HandlesBlock(HandlesBlock* next)
|
||||
: next_block_(next), next_handle_slot_(0) {}
|
||||
: next_handle_slot_(0), next_block_(next) {}
|
||||
~HandlesBlock();
|
||||
|
||||
// Reinitializes handle block for reuse.
|
||||
@@ -193,9 +175,9 @@ class Handles {
|
||||
void set_next_block(HandlesBlock* next) { next_block_ = next; }
|
||||
|
||||
private:
|
||||
HandlesBlock* next_block_; // Link to next block of handles.
|
||||
intptr_t next_handle_slot_; // Next slot for allocation in current block.
|
||||
uword data_[kHandleSizeInWords * kHandlesPerChunk]; // Handles area.
|
||||
intptr_t next_handle_slot_; // Next slot for allocation in current block.
|
||||
HandlesBlock* next_block_; // Link to next block of handles.
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HandlesBlock);
|
||||
};
|
||||
@@ -240,7 +222,7 @@ class Handles {
|
||||
};
|
||||
|
||||
static const int kVMHandleSizeInWords = 2;
|
||||
static const int kVMHandlesPerChunk = 63;
|
||||
static const int kVMHandlesPerChunk = 64;
|
||||
static const int kOffsetOfRawPtr = kWordSize;
|
||||
class VMHandles : public Handles<kVMHandleSizeInWords,
|
||||
kVMHandlesPerChunk,
|
||||
@@ -250,25 +232,12 @@ class VMHandles : public Handles<kVMHandleSizeInWords,
|
||||
|
||||
VMHandles()
|
||||
: Handles<kVMHandleSizeInWords, kVMHandlesPerChunk, kOffsetOfRawPtr>() {
|
||||
#if defined(DEBUG)
|
||||
if (FLAG_trace_handles) {
|
||||
OS::PrintErr("*** Starting a new VM handle block 0x%" Px "\n",
|
||||
reinterpret_cast<intptr_t>(this));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
~VMHandles() {
|
||||
#if defined(DEBUG)
|
||||
if (FLAG_trace_handles) {
|
||||
OS::PrintErr("*** Handle Counts for 0x(%" Px
|
||||
"):Zone = %d,Scoped = %d\n",
|
||||
reinterpret_cast<intptr_t>(this), CountZoneHandles(),
|
||||
CountScopedHandles());
|
||||
OS::PrintErr("*** Deleting VM handle block 0x%" Px "\n",
|
||||
reinterpret_cast<intptr_t>(this));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
~VMHandles();
|
||||
|
||||
// Visit all object pointers stored in the various handles.
|
||||
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||
|
||||
@@ -81,6 +81,7 @@ uword Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
|
||||
AllocateHandle(Zone* zone) {
|
||||
#if defined(DEBUG)
|
||||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread->top_handle_scope() != NULL);
|
||||
ASSERT(thread->MayAllocateHandles());
|
||||
#endif // DEBUG
|
||||
Handles* handles = zone->handles();
|
||||
|
||||
@@ -592,6 +592,7 @@ VM_UNIT_TEST_CASE(CleanupBequestNeverReceived) {
|
||||
Thread* thread = Thread::Current();
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
String& string = String::Handle(String::New(TEST_MESSAGE));
|
||||
PersistentHandle* handle =
|
||||
@@ -625,6 +626,7 @@ VM_UNIT_TEST_CASE(ReceivesSendAndExitMessage) {
|
||||
Thread* thread = Thread::Current();
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
String& string = String::Handle(String::New(TEST_MESSAGE));
|
||||
|
||||
@@ -642,6 +644,7 @@ VM_UNIT_TEST_CASE(ReceivesSendAndExitMessage) {
|
||||
Thread* thread = Thread::Current();
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ class RunKernelTask : public ThreadPool::Task {
|
||||
Thread* T = Thread::Current();
|
||||
ASSERT(I == T->isolate());
|
||||
StackZone zone(T);
|
||||
HANDLESCOPE(T);
|
||||
// Invoke main which will return the port to which load requests are sent.
|
||||
const Library& root_library =
|
||||
Library::Handle(Z, I->group()->object_store()->root_library());
|
||||
|
||||
@@ -53,6 +53,7 @@ VM_UNIT_TEST_CASE(Metric_OnDemand) {
|
||||
Thread* thread = Thread::Current();
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
MyMetric metric;
|
||||
|
||||
metric.InitInstance(Isolate::Current(), "a.b.c", "foobar", Metric::kByte);
|
||||
|
||||
@@ -1777,6 +1777,7 @@ void ProfilerService::PrintJSONImpl(Thread* thread,
|
||||
ASSERT(buffer != nullptr);
|
||||
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
profile.Build(thread, filter, buffer);
|
||||
profile.PrintProfileJSON(stream, include_code_samples);
|
||||
|
||||
@@ -501,6 +501,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TrivialRecordAllocation) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
// Filter for the class in the time range.
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id(),
|
||||
@@ -530,6 +531,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TrivialRecordAllocation) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id(),
|
||||
Dart_TimelineGetMicros(), 16000);
|
||||
@@ -576,6 +578,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_NativeAllocation) {
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
|
||||
// Filter for the class in the time range.
|
||||
@@ -614,6 +617,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_NativeAllocation) {
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
|
||||
// Filter for the class in the time range.
|
||||
@@ -628,6 +632,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_NativeAllocation) {
|
||||
{
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
NativeAllocationSampleFilter filter(Dart_TimelineGetMicros(), 16000);
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -673,6 +678,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ToggleRecordAllocation) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -689,6 +695,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ToggleRecordAllocation) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -718,6 +725,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ToggleRecordAllocation) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -755,6 +763,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_CodeTicks) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -774,6 +783,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_CodeTicks) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -828,6 +838,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_FunctionTicks) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -847,6 +858,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_FunctionTicks) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -896,6 +908,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_IntrinsicAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), double_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -908,6 +921,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_IntrinsicAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), double_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -929,6 +943,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_IntrinsicAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), double_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -955,6 +970,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), array_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -967,6 +983,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), array_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -988,6 +1005,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), array_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1009,6 +1027,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), array_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1038,6 +1057,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ContextAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), context_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1050,6 +1070,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ContextAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), context_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1069,6 +1090,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ContextAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), context_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1108,6 +1130,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ClosureAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), closure_class.id());
|
||||
filter.set_enable_vm_ticks(true);
|
||||
@@ -1131,6 +1154,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ClosureAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), closure_class.id());
|
||||
filter.set_enable_vm_ticks(true);
|
||||
@@ -1161,6 +1185,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TypedArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), float32_list_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1173,6 +1198,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TypedArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), float32_list_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1194,6 +1220,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TypedArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), float32_list_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1206,6 +1233,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TypedArrayAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), float32_list_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1237,6 +1265,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1249,6 +1278,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1268,6 +1298,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1280,6 +1311,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringAllocation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1311,6 +1343,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringInterpolation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1323,6 +1356,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringInterpolation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1348,6 +1382,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringInterpolation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1360,6 +1395,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringInterpolation) {
|
||||
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), one_byte_string_class.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1415,6 +1451,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_FunctionInline) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1432,6 +1469,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_FunctionInline) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1560,6 +1598,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_InliningIntervalBoundry) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1576,6 +1615,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_InliningIntervalBoundry) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1651,6 +1691,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ChainedSamples) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1745,6 +1786,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BasicSourcePosition) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1826,6 +1868,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BasicSourcePositionOptimized) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -1903,6 +1946,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_SourcePosition) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -2012,6 +2056,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_SourcePositionOptimized) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -2106,6 +2151,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BinaryOperatorSourcePosition) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
@@ -2223,6 +2269,7 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BinaryOperatorSourcePositionOptimized) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Profile profile;
|
||||
AllocationFilter filter(isolate->main_port(), class_a.id());
|
||||
profile.Build(thread, &filter, Profiler::sample_block_buffer());
|
||||
|
||||
@@ -1504,6 +1504,7 @@ class ProgramHashVisitor : public CodeVisitor {
|
||||
|
||||
uint32_t ProgramVisitor::Hash(Thread* thread) {
|
||||
StackZone stack_zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Zone* zone = thread->zone();
|
||||
|
||||
ProgramHashVisitor visitor(zone);
|
||||
|
||||
@@ -3265,6 +3265,7 @@ DEFINE_LEAF_RUNTIME_ENTRY(intptr_t,
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
// All registers have been saved below last-fp as if they were locals.
|
||||
const uword last_fp =
|
||||
@@ -3336,6 +3337,7 @@ DEFINE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, 1, uword last_fp) {
|
||||
Thread* thread = Thread::Current();
|
||||
Isolate* isolate = thread->isolate();
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
DeoptContext* deopt_context = isolate->deopt_context();
|
||||
DartFrameIterator iterator(last_fp, thread,
|
||||
|
||||
@@ -120,6 +120,7 @@ class RuntimeEntry : public BaseRuntimeEntry {
|
||||
Isolate* isolate = thread->isolate(); \
|
||||
TransitionGeneratedToVM transition(thread); \
|
||||
StackZone zone(thread); \
|
||||
HANDLESCOPE(thread); \
|
||||
CHECK_SIMULATOR_STACK_OVERFLOW(); \
|
||||
if (FLAG_deoptimize_on_runtime_call_every > 0) { \
|
||||
OnEveryRuntimeEntryCall(thread, "" #name, can_lazy_deopt); \
|
||||
|
||||
@@ -844,6 +844,7 @@ void Service::PostError(const String& method_name,
|
||||
const Error& error) {
|
||||
Thread* T = Thread::Current();
|
||||
StackZone zone(T);
|
||||
HANDLESCOPE(T);
|
||||
JSONStream js;
|
||||
js.Setup(zone.GetZone(), SendPort::Cast(reply_port).Id(), id, method_name,
|
||||
parameter_keys, parameter_values);
|
||||
@@ -864,6 +865,7 @@ ErrorPtr Service::InvokeMethod(Isolate* I,
|
||||
|
||||
{
|
||||
StackZone zone(T);
|
||||
HANDLESCOPE(T);
|
||||
|
||||
Instance& reply_port = Instance::Handle(Z);
|
||||
Instance& seq = String::Handle(Z);
|
||||
@@ -3225,6 +3227,7 @@ static void GetInstances(Thread* thread, JSONStream* js) {
|
||||
|
||||
// Ensure the array and handles created below are promptly destroyed.
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
ZoneGrowableHandlePtrArray<Object> storage(thread->zone(), limit);
|
||||
GetInstancesVisitor visitor(&storage, limit);
|
||||
@@ -3275,6 +3278,7 @@ static void GetInstancesAsArray(Thread* thread, JSONStream* js) {
|
||||
Array& instances = Array::Handle();
|
||||
{
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
ZoneGrowableHandlePtrArray<Object> storage(thread->zone(), 1024);
|
||||
GetInstancesVisitor visitor(&storage, kSmiMax);
|
||||
@@ -3302,6 +3306,7 @@ static const MethodParameter* const get_ports_params[] = {
|
||||
static void GetPorts(Thread* thread, JSONStream* js) {
|
||||
// Ensure the array and handles created below are promptly destroyed.
|
||||
StackZone zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
const GrowableObjectArray& ports = GrowableObjectArray::Handle(
|
||||
GrowableObjectArray::RawCast(DartLibraryCalls::LookupOpenPorts()));
|
||||
JSONObject jsobj(js);
|
||||
@@ -4885,6 +4890,8 @@ void Service::PrintJSONForVM(JSONStream* js, bool ref) {
|
||||
jsobj.AddProperty("targetCPU", CPU::Id());
|
||||
jsobj.AddProperty("version", Version::String());
|
||||
jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart");
|
||||
jsobj.AddProperty64("_nativeZoneMemoryUsage",
|
||||
ApiNativeScope::current_memory_usage());
|
||||
jsobj.AddProperty64("pid", OS::ProcessId());
|
||||
jsobj.AddPropertyTimeMillis(
|
||||
"startTime", OS::GetCurrentTimeMillis() - Dart::UptimeMillis());
|
||||
|
||||
@@ -438,6 +438,7 @@ class RunServiceTask : public ThreadPool::Task {
|
||||
Thread* T = Thread::Current();
|
||||
ASSERT(I == T->isolate());
|
||||
StackZone zone(T);
|
||||
HANDLESCOPE(T);
|
||||
// Invoke main which will set up the service port.
|
||||
const Library& root_library =
|
||||
Library::Handle(Z, I->group()->object_store()->root_library());
|
||||
|
||||
@@ -9,7 +9,21 @@
|
||||
|
||||
namespace dart {
|
||||
|
||||
ThreadState::ThreadState(bool is_os_thread) : BaseThread(is_os_thread) {}
|
||||
ThreadState::ThreadState(bool is_os_thread) : BaseThread(is_os_thread) {
|
||||
// This thread should not yet own any zones. If it does, we need to make sure
|
||||
// we've accounted for any memory it has already allocated.
|
||||
if (zone_ == nullptr) {
|
||||
ASSERT(current_zone_capacity_ == 0);
|
||||
} else {
|
||||
Zone* current = zone_;
|
||||
uintptr_t total_zone_capacity = 0;
|
||||
while (current != nullptr) {
|
||||
total_zone_capacity += current->CapacityInBytes();
|
||||
current = current->previous();
|
||||
}
|
||||
ASSERT(current_zone_capacity_ == total_zone_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadState::~ThreadState() {}
|
||||
|
||||
|
||||
@@ -40,6 +40,17 @@ class ThreadState : public BaseThread {
|
||||
|
||||
bool ZoneIsOwnedByThread(Zone* zone) const;
|
||||
|
||||
void IncrementMemoryCapacity(uintptr_t value) {
|
||||
current_zone_capacity_ += value;
|
||||
}
|
||||
|
||||
void DecrementMemoryCapacity(uintptr_t value) {
|
||||
ASSERT(current_zone_capacity_ >= value);
|
||||
current_zone_capacity_ -= value;
|
||||
}
|
||||
|
||||
uintptr_t current_zone_capacity() const { return current_zone_capacity_; }
|
||||
|
||||
StackResource* top_resource() const { return top_resource_; }
|
||||
void set_top_resource(StackResource* value) { top_resource_ = value; }
|
||||
static intptr_t top_resource_offset() {
|
||||
@@ -75,6 +86,7 @@ class ThreadState : public BaseThread {
|
||||
|
||||
OSThread* os_thread_ = nullptr;
|
||||
Zone* zone_ = nullptr;
|
||||
uintptr_t current_zone_capacity_ = 0;
|
||||
StackResource* top_resource_ = nullptr;
|
||||
LongJumpScope* long_jump_base_ = nullptr;
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ class TaskWithZoneAllocation : public ThreadPool::Task {
|
||||
Thread* thread = Thread::Current();
|
||||
// Create a zone (which is also a stack resource) and exercise it a bit.
|
||||
StackZone stack_zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Zone* zone = thread->zone();
|
||||
EXPECT_EQ(zone, stack_zone.GetZone());
|
||||
ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1);
|
||||
@@ -254,6 +255,7 @@ class SimpleTaskWithZoneAllocation : public ThreadPool::Task {
|
||||
*thread_ptr_ = thread;
|
||||
|
||||
StackZone stack_zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
Zone* zone = thread->zone();
|
||||
EXPECT_EQ(zone, stack_zone.GetZone());
|
||||
|
||||
@@ -388,6 +390,7 @@ class ICDataTestTask : public ThreadPool::Task {
|
||||
|
||||
{
|
||||
StackZone stack_zone(thread);
|
||||
HANDLESCOPE(thread);
|
||||
|
||||
ICData& ic_data = ICData::Handle();
|
||||
Array& arr = Array::Handle();
|
||||
@@ -533,6 +536,7 @@ class SafepointTestTask : public ThreadPool::Task {
|
||||
for (int i = reinterpret_cast<intptr_t>(thread);; ++i) {
|
||||
StackZone stack_zone(thread);
|
||||
Zone* zone = thread->zone();
|
||||
HANDLESCOPE(thread);
|
||||
const intptr_t kUniqueSmi = 928327281;
|
||||
Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi));
|
||||
if ((i % 100) != 0) {
|
||||
@@ -848,6 +852,7 @@ class AllocAndGCTask : public ThreadPool::Task {
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone stack_zone(thread);
|
||||
Zone* zone = stack_zone.GetZone();
|
||||
HANDLESCOPE(thread);
|
||||
String& old_str = String::Handle(zone, String::New("old", Heap::kOld));
|
||||
isolate_->group()->heap()->CollectAllGarbage();
|
||||
EXPECT(old_str.Equals("old"));
|
||||
@@ -895,6 +900,7 @@ class AllocateGlobsOfMemoryTask : public ThreadPool::Task {
|
||||
Thread* thread = Thread::Current();
|
||||
StackZone stack_zone(thread);
|
||||
Zone* zone = stack_zone.GetZone();
|
||||
HANDLESCOPE(thread);
|
||||
int count = 100 * 1000;
|
||||
while (count-- > 0) {
|
||||
String::Handle(zone, String::New("abc"));
|
||||
|
||||
+77
-31
@@ -33,6 +33,8 @@ class Zone::Segment {
|
||||
// Allocate or delete individual segments.
|
||||
static Segment* New(intptr_t size, Segment* next);
|
||||
static void DeleteSegmentList(Segment* segment);
|
||||
static void IncrementMemoryCapacity(uintptr_t size);
|
||||
static void DecrementMemoryCapacity(uintptr_t size);
|
||||
|
||||
private:
|
||||
Segment* next_;
|
||||
@@ -105,6 +107,7 @@ Zone::Segment* Zone::Segment::New(intptr_t size, Zone::Segment* next) {
|
||||
|
||||
LSAN_REGISTER_ROOT_REGION(result, sizeof(*result));
|
||||
|
||||
IncrementMemoryCapacity(size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -112,6 +115,7 @@ void Zone::Segment::DeleteSegmentList(Segment* head) {
|
||||
Segment* current = head;
|
||||
while (current != NULL) {
|
||||
intptr_t size = current->size();
|
||||
DecrementMemoryCapacity(size);
|
||||
Segment* next = current->next();
|
||||
VirtualMemory* memory = current->memory();
|
||||
#ifdef DEBUG
|
||||
@@ -137,13 +141,38 @@ void Zone::Segment::DeleteSegmentList(Segment* head) {
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::Segment::IncrementMemoryCapacity(uintptr_t size) {
|
||||
ThreadState* current_thread = ThreadState::Current();
|
||||
if (current_thread != NULL) {
|
||||
current_thread->IncrementMemoryCapacity(size);
|
||||
} else if (ApiNativeScope::Current() != NULL) {
|
||||
// If there is no current thread, we might be inside of a native scope.
|
||||
ApiNativeScope::IncrementNativeScopeMemoryCapacity(size);
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::Segment::DecrementMemoryCapacity(uintptr_t size) {
|
||||
ThreadState* current_thread = ThreadState::Current();
|
||||
if (current_thread != NULL) {
|
||||
current_thread->DecrementMemoryCapacity(size);
|
||||
} else if (ApiNativeScope::Current() != NULL) {
|
||||
// If there is no current thread, we might be inside of a native scope.
|
||||
ApiNativeScope::DecrementNativeScopeMemoryCapacity(size);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(bkonyi): We need to account for the initial chunk size when a new zone
|
||||
// is created within a new thread or ApiNativeScope when calculating high
|
||||
// watermarks or memory consumption.
|
||||
Zone::Zone()
|
||||
: position_(reinterpret_cast<uword>(&buffer_)),
|
||||
limit_(position_ + kInitialChunkSize),
|
||||
segments_(nullptr),
|
||||
previous_(nullptr),
|
||||
head_(NULL),
|
||||
large_segments_(NULL),
|
||||
previous_(NULL),
|
||||
handles_() {
|
||||
ASSERT(Utils::IsAligned(position_, kAlignment));
|
||||
Segment::IncrementMemoryCapacity(kInitialChunkSize);
|
||||
#ifdef DEBUG
|
||||
// Zap the entire initial buffer.
|
||||
memset(&buffer_, kZapUninitializedByte, kInitialChunkSize);
|
||||
@@ -152,64 +181,70 @@ Zone::Zone()
|
||||
|
||||
Zone::~Zone() {
|
||||
if (FLAG_trace_zones) {
|
||||
Print();
|
||||
DumpZoneSizes();
|
||||
}
|
||||
Segment::DeleteSegmentList(segments_);
|
||||
DeleteAll();
|
||||
Segment::DecrementMemoryCapacity(kInitialChunkSize);
|
||||
}
|
||||
|
||||
void Zone::Reset() {
|
||||
void Zone::DeleteAll() {
|
||||
// Traverse the chained list of segments, zapping (in debug mode)
|
||||
// and freeing every zone segment.
|
||||
Segment::DeleteSegmentList(segments_);
|
||||
segments_ = nullptr;
|
||||
|
||||
if (head_ != NULL) {
|
||||
Segment::DeleteSegmentList(head_);
|
||||
}
|
||||
if (large_segments_ != NULL) {
|
||||
Segment::DeleteSegmentList(large_segments_);
|
||||
}
|
||||
// Reset zone state.
|
||||
#ifdef DEBUG
|
||||
memset(&buffer_, kZapDeletedByte, kInitialChunkSize);
|
||||
#endif
|
||||
position_ = reinterpret_cast<uword>(&buffer_);
|
||||
limit_ = position_ + kInitialChunkSize;
|
||||
small_segment_capacity_ = 0;
|
||||
previous_ = nullptr;
|
||||
head_ = NULL;
|
||||
large_segments_ = NULL;
|
||||
previous_ = NULL;
|
||||
handles_.Reset();
|
||||
}
|
||||
|
||||
uintptr_t Zone::SizeInBytes() const {
|
||||
uintptr_t size = 0;
|
||||
if (segments_ == nullptr) {
|
||||
for (Segment* s = large_segments_; s != NULL; s = s->next()) {
|
||||
size += s->size();
|
||||
}
|
||||
if (head_ == NULL) {
|
||||
return size + (position_ - reinterpret_cast<uword>(&buffer_));
|
||||
}
|
||||
size += kInitialChunkSize;
|
||||
for (Segment* s = segments_->next(); s != nullptr; s = s->next()) {
|
||||
for (Segment* s = head_->next(); s != NULL; s = s->next()) {
|
||||
size += s->size();
|
||||
}
|
||||
return size + (position_ - segments_->start());
|
||||
return size + (position_ - head_->start());
|
||||
}
|
||||
|
||||
uintptr_t Zone::CapacityInBytes() const {
|
||||
uintptr_t size = kInitialChunkSize;
|
||||
for (Segment* s = segments_; s != nullptr; s = s->next()) {
|
||||
uintptr_t size = 0;
|
||||
for (Segment* s = large_segments_; s != NULL; s = s->next()) {
|
||||
size += s->size();
|
||||
}
|
||||
if (head_ == NULL) {
|
||||
return size + kInitialChunkSize;
|
||||
}
|
||||
size += kInitialChunkSize;
|
||||
for (Segment* s = head_; s != NULL; s = s->next()) {
|
||||
size += s->size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void Zone::Print() const {
|
||||
intptr_t segment_size = CapacityInBytes();
|
||||
intptr_t scoped_handle_size = handles_.ScopedHandlesCapacityInBytes();
|
||||
intptr_t zone_handle_size = handles_.ZoneHandlesCapacityInBytes();
|
||||
intptr_t total_size = segment_size + scoped_handle_size + zone_handle_size;
|
||||
OS::PrintErr("Zone(%p, segments: %" Pd ", scoped_handles: %" Pd
|
||||
", zone_handles: %" Pd ", total: %" Pd ")\n",
|
||||
this, segment_size, scoped_handle_size, zone_handle_size,
|
||||
total_size);
|
||||
}
|
||||
|
||||
uword Zone::AllocateExpand(intptr_t size) {
|
||||
ASSERT(size >= 0);
|
||||
if (FLAG_trace_zones) {
|
||||
OS::PrintErr("*** Expanding zone 0x%" Px "\n",
|
||||
reinterpret_cast<intptr_t>(this));
|
||||
Print();
|
||||
DumpZoneSizes();
|
||||
}
|
||||
// Make sure the requested size is already properly aligned and that
|
||||
// there isn't enough room in the Zone to satisfy the request.
|
||||
@@ -239,13 +274,13 @@ uword Zone::AllocateExpand(intptr_t size) {
|
||||
ASSERT(next_size >= kSegmentSize);
|
||||
|
||||
// Allocate another segment and chain it up.
|
||||
segments_ = Segment::New(next_size, segments_);
|
||||
head_ = Segment::New(next_size, head_);
|
||||
small_segment_capacity_ += next_size;
|
||||
|
||||
// Recompute 'position' and 'limit' based on the new head segment.
|
||||
uword result = Utils::RoundUp(segments_->start(), kAlignment);
|
||||
uword result = Utils::RoundUp(head_->start(), kAlignment);
|
||||
position_ = result + size;
|
||||
limit_ = segments_->end();
|
||||
limit_ = head_->end();
|
||||
ASSERT(position_ <= limit_);
|
||||
return result;
|
||||
}
|
||||
@@ -261,9 +296,9 @@ uword Zone::AllocateLargeSegment(intptr_t size) {
|
||||
// Create a new large segment and chain it up.
|
||||
// Account for book keeping fields in size.
|
||||
size += Utils::RoundUp(sizeof(Segment), kAlignment);
|
||||
segments_ = Segment::New(size, segments_);
|
||||
large_segments_ = Segment::New(size, large_segments_);
|
||||
|
||||
uword result = Utils::RoundUp(segments_->start(), kAlignment);
|
||||
uword result = Utils::RoundUp(large_segments_->start(), kAlignment);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -302,6 +337,17 @@ char* Zone::ConcatStrings(const char* a, const char* b, char join) {
|
||||
return copy;
|
||||
}
|
||||
|
||||
void Zone::DumpZoneSizes() {
|
||||
intptr_t size = 0;
|
||||
for (Segment* s = large_segments_; s != NULL; s = s->next()) {
|
||||
size += s->size();
|
||||
}
|
||||
OS::PrintErr("*** Zone(0x%" Px
|
||||
") size in bytes,"
|
||||
" Total = %" Pd " Large Segments = %" Pd "\n",
|
||||
reinterpret_cast<intptr_t>(this), SizeInBytes(), size);
|
||||
}
|
||||
|
||||
void Zone::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
||||
Zone* zone = this;
|
||||
while (zone != NULL) {
|
||||
|
||||
+10
-7
@@ -67,9 +67,6 @@ class Zone {
|
||||
// Computes the amount of space used in the zone.
|
||||
uintptr_t CapacityInBytes() const;
|
||||
|
||||
// Dump the current allocated sizes in the zone object.
|
||||
void Print() const;
|
||||
|
||||
// Structure for managing handles allocation.
|
||||
VMHandles* handles() { return &handles_; }
|
||||
|
||||
@@ -98,7 +95,7 @@ class Zone {
|
||||
~Zone(); // Delete all memory associated with the zone.
|
||||
|
||||
// Default initial chunk size.
|
||||
static const intptr_t kInitialChunkSize = 128;
|
||||
static const intptr_t kInitialChunkSize = 1 * KB;
|
||||
|
||||
// Default segment size.
|
||||
static const intptr_t kSegmentSize = 64 * KB;
|
||||
@@ -122,7 +119,7 @@ class Zone {
|
||||
void Link(Zone* current_zone) { previous_ = current_zone; }
|
||||
|
||||
// Delete all objects and free all memory allocated in the zone.
|
||||
void Reset();
|
||||
void DeleteAll();
|
||||
|
||||
// Does not actually free any memory. Enables templated containers like
|
||||
// BaseGrowableArray to use different allocators.
|
||||
@@ -137,6 +134,9 @@ class Zone {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Dump the current allocated sizes in the zone object.
|
||||
void DumpZoneSizes();
|
||||
|
||||
// Overflow check (FATAL) for array length.
|
||||
template <class ElementType>
|
||||
static inline void CheckLength(intptr_t len);
|
||||
@@ -155,8 +155,11 @@ class Zone {
|
||||
// Total size of all segments in [head_].
|
||||
intptr_t small_segment_capacity_ = 0;
|
||||
|
||||
// List of all segments allocated in this zone; may be NULL.
|
||||
Segment* segments_;
|
||||
// The current head segment; may be NULL.
|
||||
Segment* head_;
|
||||
|
||||
// List of large segments allocated in this zone; may be NULL.
|
||||
Segment* large_segments_;
|
||||
|
||||
// Used for chaining zones in order to allow unwinding of stacks.
|
||||
Zone* previous_;
|
||||
|
||||
@@ -165,6 +165,21 @@ TEST_CASE(PrintToString) {
|
||||
EXPECT_STREQ("Hello World!", result);
|
||||
}
|
||||
|
||||
VM_UNIT_TEST_CASE(NativeScopeZoneAllocation) {
|
||||
ASSERT(ApiNativeScope::Current() == NULL);
|
||||
ASSERT(Thread::Current() == NULL);
|
||||
EXPECT_EQ(0UL, ApiNativeScope::current_memory_usage());
|
||||
{
|
||||
ApiNativeScope scope;
|
||||
EXPECT_EQ(scope.zone()->CapacityInBytes(),
|
||||
ApiNativeScope::current_memory_usage());
|
||||
(void)Dart_ScopeAllocate(2048);
|
||||
EXPECT_EQ(scope.zone()->CapacityInBytes(),
|
||||
ApiNativeScope::current_memory_usage());
|
||||
}
|
||||
EXPECT_EQ(0UL, ApiNativeScope::current_memory_usage());
|
||||
}
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
// Allow for pooling in the malloc implementation.
|
||||
static const int64_t kRssSlack = 20 * MB;
|
||||
|
||||
Reference in New Issue
Block a user