Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ff8caf9

Browse files
rmacnak-googleCommit Queue
authored and
Commit Queue
committed
[vm] Remove quadratic time spent zapping scoped handles.
TEST=ci Change-Id: I7faaf61ff33ae54795db4da1b253053abea0d5a9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/271581 Commit-Queue: Ryan Macnak <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
1 parent 01fba61 commit ff8caf9

File tree

4 files changed

+41
-36
lines changed

4 files changed

+41
-36
lines changed

runtime/vm/handles.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,18 @@ HandleScope::~HandleScope() {
9090
ASSERT(thread()->zone() != NULL);
9191
VMHandles* handles = thread()->zone()->handles();
9292
ASSERT(handles != NULL);
93+
#if defined(DEBUG)
94+
VMHandles::HandlesBlock* last = handles->scoped_blocks_;
95+
#endif
9396
handles->scoped_blocks_ = saved_handle_block_;
9497
handles->scoped_blocks_->set_next_handle_slot(saved_handle_slot_);
9598
#if defined(DEBUG)
96-
handles->VerifyScopedHandleState();
97-
handles->ZapFreeScopedHandles();
99+
VMHandles::HandlesBlock* block = handles->scoped_blocks_;
100+
for (;;) {
101+
block->ZapFreeHandles();
102+
if (block == last) break;
103+
block = block->next_block();
104+
}
98105
ASSERT(thread()->top_handle_scope() == this);
99106
thread()->set_top_handle_scope(link_);
100107
#endif

runtime/vm/handles.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,14 +218,6 @@ class Handles {
218218
// Allocates a new handle block and links it up.
219219
void SetupNextZoneBlock();
220220

221-
#if defined(DEBUG)
222-
// Verifies consistency of handle blocks after a scope is destroyed.
223-
void VerifyScopedHandleState();
224-
225-
// Zaps the free scoped handles to an uninitialized value.
226-
void ZapFreeScopedHandles();
227-
#endif
228-
229221
HandlesBlock* zone_blocks_; // List of zone handles.
230222
HandlesBlock first_scoped_block_; // First block of scoped handles.
231223
HandlesBlock* scoped_blocks_; // List of scoped handles.

runtime/vm/handles_impl.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -207,32 +207,6 @@ void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
207207
zone_blocks_ = new HandlesBlock(zone_blocks_);
208208
}
209209

210-
#if defined(DEBUG)
211-
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
212-
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
213-
VerifyScopedHandleState() {
214-
HandlesBlock* block = &first_scoped_block_;
215-
const intptr_t end_index = (kHandleSizeInWords * kHandlesPerChunk);
216-
do {
217-
if (scoped_blocks_ == block && block->next_handle_slot() <= end_index) {
218-
return;
219-
}
220-
block = block->next_block();
221-
} while (block != NULL);
222-
ASSERT(false);
223-
}
224-
225-
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
226-
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
227-
ZapFreeScopedHandles() {
228-
HandlesBlock* block = scoped_blocks_;
229-
while (block != NULL) {
230-
block->ZapFreeHandles();
231-
block = block->next_block();
232-
}
233-
}
234-
#endif
235-
236210
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
237211
int Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
238212
CountScopedHandles() const {

runtime/vm/zone_test.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,36 @@ ISOLATE_UNIT_TEST_CASE(ZonesNotLimitedByCompressedHeap) {
263263
}
264264
#endif // defined(DART_COMPRESSED_POINTERS)
265265

266+
ISOLATE_UNIT_TEST_CASE(ZoneVerificationScaling) {
267+
// This ought to complete in O(n), not O(n^2).
268+
const intptr_t n = 1000000;
269+
270+
StackZone stack_zone(thread);
271+
Zone* zone = stack_zone.GetZone();
272+
273+
{
274+
HANDLESCOPE(thread);
275+
for (intptr_t i = 0; i < n; i++) {
276+
const Object& a = Object::Handle(zone);
277+
DEBUG_ASSERT(!a.IsNotTemporaryScopedHandle());
278+
USE(a);
279+
const Object& b = Object::ZoneHandle(zone);
280+
DEBUG_ASSERT(b.IsNotTemporaryScopedHandle());
281+
USE(b);
282+
}
283+
// Leaves lots of HandleBlocks for recycling.
284+
}
285+
286+
for (intptr_t i = 0; i < n; i++) {
287+
HANDLESCOPE(thread);
288+
const Object& a = Object::Handle(zone);
289+
DEBUG_ASSERT(!a.IsNotTemporaryScopedHandle());
290+
USE(a);
291+
const Object& b = Object::ZoneHandle(zone);
292+
DEBUG_ASSERT(b.IsNotTemporaryScopedHandle());
293+
USE(b);
294+
// Should not visit those recyclable blocks over and over again.
295+
}
296+
}
297+
266298
} // namespace dart

0 commit comments

Comments
 (0)