[vm] Remove code collection.
Code collection interacts badly with
- warming up compiled code
- retaining pre-compiled code
- code coverage
- hot reload (deopting to an old version of a function)
Change-Id: Id269a6c3281e577d4f600f0c158af9e62f6b49ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99722
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/pkg/status_file/test/data/standalone_2_vm.status b/pkg/status_file/test/data/standalone_2_vm.status
index fd09ed8..01c5b89 100644
--- a/pkg/status_file/test/data/standalone_2_vm.status
+++ b/pkg/status_file/test/data/standalone_2_vm.status
@@ -48,7 +48,6 @@
io/test_extension_test: Skip # Platform.executable
io/test_extension_fail_test: Skip # Platform.executable
io/platform_test: Skip # Platform.executable
-io/code_collection_test: Skip # Platform.executable
full_coverage_test: Skip # Platform.executable
regress_26031_test: Skip # Platform.resolvedExecutable
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 6632130..e191728 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -843,9 +843,6 @@
#if !defined(TARGET_ARCH_IA32)
vm_options.AddArgument("--link_natives_lazily");
#endif
-#if !defined(PRODUCT)
- vm_options.AddArgument("--collect_code=false");
-#endif
}
char* error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index d0916b9..39d5959 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1076,9 +1076,6 @@
if (Options::gen_snapshot_kind() == kAppJIT) {
vm_options.AddArgument("--fields_may_be_reset");
-#if !defined(PRODUCT)
- vm_options.AddArgument("--collect_code=false");
-#endif
}
#if defined(DART_PRECOMPILED_RUNTIME)
vm_options.AddArgument("--precompilation");
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
index 48db21c..af8d622 100644
--- a/runtime/vm/compilation_trace.cc
+++ b/runtime/vm/compilation_trace.cc
@@ -365,11 +365,6 @@
return Object::null();
}
- // Prevent premature code collection due to major GC during startup.
- if (function.usage_counter() < Function::kGraceUsageCounter) {
- function.set_usage_counter(Function::kGraceUsageCounter);
- }
-
error_ = Compiler::CompileFunction(thread_, function);
if (error_.IsError()) {
return error_.raw();
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 92b725f..307c7ad 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1173,9 +1173,6 @@
// immediate objects (Smis) or permanent objects (vm-isolate heap or
// image pages). Here we choose to skip the barrier for any constant on
// the assumption it will remain reachable through the object pool.
- // TODO(concurrent-marking): Consider ensuring marking is not in progress
- // when code is disabled or only omitting the barrier if code collection
- // is disabled.
return !BindsToConstant();
}
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 412e6b0..1a7fd29 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -101,7 +101,6 @@
#endif
FLAG_background_compilation = false;
- FLAG_collect_code = false;
FLAG_enable_mirrors = false;
// TODO(dacoharkes): Ffi support in AOT
// https://github.com/dart-lang/sdk/issues/35765
@@ -427,12 +426,6 @@
}
#endif // !defined(PRODUCT)
- if (function.is_intrinsic() &&
- (function.usage_counter() < Function::kGraceUsageCounter)) {
- // Intrinsic functions may execute without incrementing their usage counter.
- // Give them a non-zero initial usage to prevent premature code collection.
- function.set_usage_counter(Function::kGraceUsageCounter);
- }
if (!function.IsOptimizable()) {
// A function with huge unoptimized code can become non-optimizable
// after generating unoptimized code.
@@ -786,7 +779,6 @@
}
done = true;
}
-
}
}
return result->raw();
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index d7b662d..a406f01 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -58,7 +58,7 @@
P(background_compilation, bool, USING_MULTICORE, \
"Run optimizing compilation in background") \
P(causal_async_stacks, bool, !USING_PRODUCT, "Improved async stacks") \
- P(collect_code, bool, true, "Attempt to GC infrequently used code.") \
+ P(collect_code, bool, false, "Attempt to GC infrequently used code.") \
P(collect_dynamic_function_names, bool, true, \
"Collects all dynamic function names to identify unique targets") \
P(compactor_tasks, int, 2, \
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 7ff24be..ec644c0 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -21,92 +21,6 @@
namespace dart {
-// Collects a list of RawFunction whose code_ or unoptimized_code_ slots were
-// treated as weak (not visited) during marking because they had low usage.
-// These slots (and the corresponding entry_point_ caches) must be cleared after
-// marking if the target RawCode were not otherwise marked. (--collect-code)
-class SkippedCodeFunctions {
- public:
- SkippedCodeFunctions() {}
-
- void Add(RawFunction* func) {
- // With concurrent mark, we hold raw pointers across safepoints.
- ASSERT(func->IsOldObject());
-
- skipped_code_functions_.Add(func);
- }
-
- void DetachCode() {
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
-#else
- Thread* thread = Thread::Current();
- StackZone zone(thread); // For log prints.
- HANDLESCOPE(thread);
-
- intptr_t unoptimized_code_count = 0;
- intptr_t current_code_count = 0;
- for (int i = 0; i < skipped_code_functions_.length(); i++) {
- RawFunction* func = skipped_code_functions_[i];
- RawCode* code = func->ptr()->code_;
- if (!code->IsMarked()) {
- // If the code wasn't strongly visited through other references
- // after skipping the function's code pointer, then we disconnect the
- // code from the function.
- if (FLAG_enable_interpreter && Function::HasBytecode(func)) {
- func->StorePointer(&(func->ptr()->code_),
- StubCode::InterpretCall().raw());
- uword entry_point = StubCode::InterpretCall().EntryPoint();
- func->ptr()->entry_point_ = entry_point;
- func->ptr()->unchecked_entry_point_ = entry_point;
- } else {
- func->StorePointer(&(func->ptr()->code_),
- StubCode::LazyCompile().raw());
- uword entry_point = StubCode::LazyCompile().EntryPoint();
- func->ptr()->entry_point_ = entry_point;
- func->ptr()->unchecked_entry_point_ = entry_point;
- }
- if (FLAG_log_code_drop) {
- // NOTE: This code runs while GC is in progress and runs within
- // a NoHandleScope block. Hence it is not okay to use a regular Zone
- // or Scope handle. We use a direct stack handle so the raw pointer in
- // this handle is not traversed. The use of a handle is mainly to
- // be able to reuse the handle based code and avoid having to add
- // helper functions to the raw object interface.
- String name;
- name = func->ptr()->name_;
- THR_Print("Detaching code: %s\n", name.ToCString());
- current_code_count++;
- }
- }
-
- code = func->ptr()->unoptimized_code_;
- if (!code->IsMarked()) {
- // If the code wasn't strongly visited through other references
- // after skipping the function's code pointer, then we disconnect the
- // code from the function.
- func->StorePointer(&(func->ptr()->unoptimized_code_), Code::null());
- if (FLAG_log_code_drop) {
- unoptimized_code_count++;
- }
- }
- }
- if (FLAG_log_code_drop) {
- THR_Print(" total detached current: %" Pd "\n", current_code_count);
- THR_Print(" total detached unoptimized: %" Pd "\n",
- unoptimized_code_count);
- }
- // Clean up.
- skipped_code_functions_.Clear();
-#endif // !DART_PRECOMPILED_RUNTIME
- }
-
- private:
- MallocGrowableArray<RawFunction*> skipped_code_functions_;
-
- DISALLOW_COPY_AND_ASSIGN(SkippedCodeFunctions);
-};
-
class MarkerWorkList : public ValueObject {
public:
explicit MarkerWorkList(MarkingStack* marking_stack)
@@ -172,8 +86,7 @@
MarkingVisitorBase(Isolate* isolate,
PageSpace* page_space,
MarkingStack* marking_stack,
- MarkingStack* deferred_marking_stack,
- SkippedCodeFunctions* skipped_code_functions)
+ MarkingStack* deferred_marking_stack)
: ObjectPointerVisitor(isolate),
thread_(Thread::Current()),
#ifndef PRODUCT
@@ -185,7 +98,6 @@
work_list_(marking_stack),
deferred_work_list_(deferred_marking_stack),
delayed_weak_properties_(NULL),
- skipped_code_functions_(skipped_code_functions),
marked_bytes_(0),
marked_micros_(0) {
ASSERT(thread_->isolate() == isolate);
@@ -198,7 +110,6 @@
}
~MarkingVisitorBase() {
- delete skipped_code_functions_;
#ifndef PRODUCT
delete[] class_stats_count_;
delete[] class_stats_size_;
@@ -286,13 +197,6 @@
}
}
- bool visit_function_code() const { return skipped_code_functions_ == NULL; }
-
- virtual void add_skipped_code_function(RawFunction* func) {
- ASSERT(!visit_function_code());
- skipped_code_functions_->Add(func);
- }
-
void EnqueueWeakProperty(RawWeakProperty* raw_weak) {
ASSERT(raw_weak->IsHeapObject());
ASSERT(raw_weak->IsOldObject());
@@ -346,10 +250,6 @@
// Called when all marking is complete.
void Finalize() {
work_list_.Finalize();
- // Detach code from functions.
- if (skipped_code_functions_ != NULL) {
- skipped_code_functions_->DetachCode();
- }
// Clear pending weak properties.
RawWeakProperty* cur_weak = delayed_weak_properties_;
delayed_weak_properties_ = NULL;
@@ -447,7 +347,6 @@
MarkerWorkList work_list_;
MarkerWorkList deferred_work_list_;
RawWeakProperty* delayed_weak_properties_;
- SkippedCodeFunctions* skipped_code_functions_;
uintptr_t marked_bytes_;
int64_t marked_micros_;
@@ -881,7 +780,7 @@
delete[] visitors_;
}
-void GCMarker::StartConcurrentMark(PageSpace* page_space, bool collect_code) {
+void GCMarker::StartConcurrentMark(PageSpace* page_space) {
isolate_->EnableIncrementalBarrier(&marking_stack_, &deferred_marking_stack_);
const intptr_t num_tasks = FLAG_marker_tasks;
@@ -901,11 +800,8 @@
ResetRootSlices();
for (intptr_t i = 0; i < num_tasks; i++) {
ASSERT(visitors_[i] == NULL);
- SkippedCodeFunctions* skipped_code_functions =
- collect_code ? new SkippedCodeFunctions() : NULL;
visitors_[i] = new SyncMarkingVisitor(isolate_, page_space, &marking_stack_,
- &deferred_marking_stack_,
- skipped_code_functions);
+ &deferred_marking_stack_);
// Begin marking on a helper thread.
bool result = Dart::thread_pool()->Run(
@@ -920,7 +816,7 @@
}
}
-void GCMarker::MarkObjects(PageSpace* page_space, bool collect_code) {
+void GCMarker::MarkObjects(PageSpace* page_space) {
if (isolate_->marking_stack() != NULL) {
isolate_->DisableIncrementalBarrier();
}
@@ -933,11 +829,8 @@
TIMELINE_FUNCTION_GC_DURATION(thread, "Mark");
int64_t start = OS::GetCurrentMonotonicMicros();
// Mark everything on main thread.
- SkippedCodeFunctions* skipped_code_functions =
- collect_code ? new SkippedCodeFunctions() : NULL;
UnsyncMarkingVisitor mark(isolate_, page_space, &marking_stack_,
- &deferred_marking_stack_,
- skipped_code_functions);
+ &deferred_marking_stack_);
ResetRootSlices();
IterateRoots(&mark);
mark.ProcessDeferredMarking();
@@ -965,11 +858,8 @@
visitor = visitors_[i];
visitors_[i] = NULL;
} else {
- SkippedCodeFunctions* skipped_code_functions =
- collect_code ? new SkippedCodeFunctions() : NULL;
visitor = new SyncMarkingVisitor(
- isolate_, page_space, &marking_stack_, &deferred_marking_stack_,
- skipped_code_functions);
+ isolate_, page_space, &marking_stack_, &deferred_marking_stack_);
}
bool result = Dart::thread_pool()->Run(new ParallelMarkTask(
diff --git a/runtime/vm/heap/marker.h b/runtime/vm/heap/marker.h
index 6108e21..9216445 100644
--- a/runtime/vm/heap/marker.h
+++ b/runtime/vm/heap/marker.h
@@ -35,11 +35,11 @@
// Mark roots synchronously, then spawn tasks to concurrently drain the
// marking queue. Only called when no marking or sweeping is in progress.
// Marking must later be finalized by calling MarkObjects.
- void StartConcurrentMark(PageSpace* page_space, bool collect_code);
+ void StartConcurrentMark(PageSpace* page_space);
// (Re)mark roots, drain the marking queue and finalize weak references.
// Does not required StartConcurrentMark to have been previously called.
- void MarkObjects(PageSpace* page_space, bool collect_code);
+ void MarkObjects(PageSpace* page_space);
intptr_t marked_words() const { return marked_bytes_ >> kWordSizeLog2; }
intptr_t MarkedWordsPerMicro() const;
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 5ef2454..4f0b6fc 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -40,18 +40,6 @@
print_free_list_after_gc,
false,
"Print free list statistics after a GC");
-DEFINE_FLAG(int,
- code_collection_interval_in_us,
- 30000000,
- "Time between attempts to collect unused code.");
-DEFINE_FLAG(bool,
- log_code_drop,
- false,
- "Emit a log message when pointers to unused code are dropped.");
-DEFINE_FLAG(bool,
- always_drop_code,
- false,
- "Always try to drop code if the function's usage counter is >= 0");
DEFINE_FLAG(bool, log_growth, false, "Log PageSpace growth policy decisions.");
HeapPage* HeapPage::Allocate(intptr_t size_in_words,
@@ -919,23 +907,6 @@
}
#endif // PRODUCT
-bool PageSpace::ShouldCollectCode() {
- // Try to collect code if enough time has passed since the last attempt.
- const int64_t start = OS::GetCurrentMonotonicMicros();
- const int64_t last_code_collection_in_us =
- page_space_controller_.last_code_collection_in_us();
-
- if ((start - last_code_collection_in_us) >
- FLAG_code_collection_interval_in_us) {
- if (FLAG_log_code_drop) {
- OS::PrintErr("Trying to detach code.\n");
- }
- page_space_controller_.set_last_code_collection_in_us(start);
- return true;
- }
- return false;
-}
-
void PageSpace::WriteProtectCode(bool read_only) {
if (FLAG_write_protect_code) {
MutexLocker ml(pages_lock_);
@@ -1107,13 +1078,6 @@
SpaceUsage usage_before = GetCurrentUsage();
// Mark all reachable old-gen objects.
-#if defined(PRODUCT)
- bool collect_code = FLAG_collect_code && ShouldCollectCode();
-#else
- bool collect_code = FLAG_collect_code && ShouldCollectCode() &&
- !isolate->HasAttemptedReload();
-#endif // !defined(PRODUCT)
-
if (marker_ == NULL) {
ASSERT(phase() == kDone);
marker_ = new GCMarker(isolate, heap_);
@@ -1123,12 +1087,12 @@
if (!finalize) {
ASSERT(phase() == kDone);
- marker_->StartConcurrentMark(this, collect_code);
+ marker_->StartConcurrentMark(this);
return;
}
NOT_IN_PRODUCT(isolate->class_table()->ResetCountersOld());
- marker_->MarkObjects(this, collect_code);
+ marker_->MarkObjects(this);
usage_.used_in_words = marker_->marked_words() + allocated_black_in_words_;
allocated_black_in_words_ = 0;
mark_words_per_micro_ = marker_->MarkedWordsPerMicro();
@@ -1393,7 +1357,6 @@
desired_utilization_((100.0 - heap_growth_ratio) / 100.0),
heap_growth_max_(heap_growth_max),
garbage_collection_time_ratio_(garbage_collection_time_ratio),
- last_code_collection_in_us_(OS::GetCurrentMonotonicMicros()),
idle_gc_threshold_in_words_(0) {
intptr_t grow_heap = heap_growth_max / 2;
gc_threshold_in_words_ =
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 8844ee7..c1608af 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -15,8 +15,6 @@
namespace dart {
-DECLARE_FLAG(bool, log_code_drop);
-DECLARE_FLAG(bool, always_drop_code);
DECLARE_FLAG(bool, write_protect_code);
// Forward declarations.
@@ -227,11 +225,6 @@
int64_t end);
void EvaluateAfterLoading(SpaceUsage after);
- int64_t last_code_collection_in_us() { return last_code_collection_in_us_; }
- void set_last_code_collection_in_us(int64_t t) {
- last_code_collection_in_us_ = t;
- }
-
void set_last_usage(SpaceUsage current) { last_usage_ = current; }
void Enable() { is_enabled_ = true; }
@@ -261,10 +254,6 @@
// we grow the heap more aggressively.
const int garbage_collection_time_ratio_;
- // The time in microseconds of the last time we tried to collect unused
- // code.
- int64_t last_code_collection_in_us_;
-
// Perform a synchronous GC when capacity exceeds this amount.
intptr_t gc_threshold_in_words_;
@@ -346,10 +335,6 @@
RawObject* FindObject(FindObjectVisitor* visitor,
HeapPage::PageType type) const;
- // Checks if enough time has elapsed since the last attempt to collect
- // code.
- bool ShouldCollectCode();
-
// Collect the garbage in the page space using mark-sweep or mark-compact.
void CollectGarbage(bool compact, bool finalize);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index ae55ce6..92e2c88 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -69,7 +69,6 @@
static void DeterministicModeHandler(bool value) {
if (value) {
FLAG_background_compilation = false; // Timing dependent.
- FLAG_collect_code = false; // Timing dependent.
FLAG_concurrent_mark = false; // Timing dependent.
FLAG_concurrent_sweep = false; // Timing dependent.
FLAG_random_seed = 0x44617274; // "Dart"
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 8a191b4..b912fcb 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1971,9 +1971,6 @@
class Function : public Object {
public:
- // A value to prevent premature code collection. lg(32) = 5 major GCs.
- static constexpr intptr_t kGraceUsageCounter = 32;
-
RawString* name() const { return raw_ptr()->name_; }
RawString* UserVisibleName() const; // Same as scrubbed name.
RawString* QualifiedScrubbedName() const {
@@ -7449,8 +7446,6 @@
friend class TwoByteString;
friend class ExternalOneByteString;
friend class ExternalTwoByteString;
- // So that SkippedCodeFunctions can print a debug string from a NoHandleScope.
- friend class SkippedCodeFunctions;
friend class RawOneByteString;
friend class RODataSerializationCluster; // SetHash
};
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 78a9445..27d808f 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -427,6 +427,7 @@
REGULAR_VISITOR(TypeRef)
REGULAR_VISITOR(TypeParameter)
REGULAR_VISITOR(PatchClass)
+REGULAR_VISITOR(Function)
COMPRESSED_VISITOR(Closure)
REGULAR_VISITOR(ClosureData)
REGULAR_VISITOR(SignatureData)
@@ -495,73 +496,6 @@
// Smi has no heap representation.
UNREACHABLE_VISITOR(Smi)
-bool RawFunction::CheckUsageCounter(RawFunction* raw_fun) {
- // NOTE: This code runs while GC is in progress and runs within
- // a NoHandleScope block. Hence it is not okay to use regular Zone or
- // Scope handles. We use direct stack handles, and so the raw pointers in
- // these handles are not traversed. The use of handles is mainly to
- // be able to reuse the handle based code and avoid having to add
- // helper functions to the raw object interface.
- Function fn;
- fn = raw_fun;
-
- // The function may not have code.
- if (!fn.HasCode()) return false;
- // These may not increment the usage counter.
- if (fn.is_intrinsic()) return false;
-
- if (fn.usage_counter() >= 0) {
- fn.SetUsageCounter(fn.usage_counter() / 2);
- }
- return FLAG_always_drop_code || (fn.usage_counter() == 0);
-}
-
-bool RawFunction::ShouldVisitCode(RawCode* raw_code) {
- // NOTE: This code runs while GC is in progress and runs within
- // a NoHandleScope block. Hence it is not okay to use regular Zone or
- // Scope handles. We use direct stack handles, and so the raw pointers in
- // these handles are not traversed. The use of handles is mainly to
- // be able to reuse the handle based code and avoid having to add
- // helper functions to the raw object interface.
- Code code;
- code = raw_code;
- if (code.IsNull()) return true;
- if (code.is_optimized()) return true;
- if (code.HasBreakpoint()) return true;
- return false;
-}
-
-intptr_t RawFunction::VisitFunctionPointers(RawFunction* raw_obj,
- ObjectPointerVisitor* visitor) {
- if (visitor->visit_function_code() || !CheckUsageCounter(raw_obj)) {
- visitor->VisitPointers(raw_obj->from(), raw_obj->to());
- return Function::InstanceSize();
- }
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
-#else
- visitor->VisitPointers(raw_obj->from(), raw_obj->to_no_code());
-
- visitor->VisitPointer(
- reinterpret_cast<RawObject**>(&raw_obj->ptr()->bytecode_));
-
- if (ShouldVisitCode(raw_obj->ptr()->code_)) {
- visitor->VisitPointer(
- reinterpret_cast<RawObject**>(&raw_obj->ptr()->code_));
- } else {
- visitor->add_skipped_code_function(raw_obj);
- }
-
- if (ShouldVisitCode(raw_obj->ptr()->unoptimized_code_)) {
- visitor->VisitPointer(
- reinterpret_cast<RawObject**>(&raw_obj->ptr()->unoptimized_code_));
- } else {
- visitor->add_skipped_code_function(raw_obj);
- }
-#endif
- return Function::InstanceSize();
-}
-
bool RawCode::ContainsPC(RawObject* raw_obj, uword pc) {
if (raw_obj->IsCode()) {
RawCode* raw_code = static_cast<RawCode*>(raw_obj);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 3967064..05d60dd 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -693,7 +693,6 @@
friend class SizeExcludingClassVisitor; // GetClassId
friend class InstanceAccumulator; // GetClassId
friend class RetainingPathVisitor; // GetClassId
- friend class SkippedCodeFunctions; // StorePointer
friend class ImageReader; // tags_ check
friend class ImageWriter;
friend class AssemblyImageWriter;
@@ -875,15 +874,10 @@
static constexpr intptr_t kMaxOptionalParametersBits = 14;
private:
- // So that the SkippedCodeFunctions::DetachCode can null out the code fields.
- friend class SkippedCodeFunctions;
friend class Class;
RAW_HEAP_OBJECT_IMPLEMENTATION(Function);
- static bool ShouldVisitCode(RawCode* raw_code);
- static bool CheckUsageCounter(RawFunction* raw_fun);
-
uword entry_point_; // Accessed from generated code.
uword unchecked_entry_point_; // Accessed from generated code.
@@ -1329,7 +1323,6 @@
friend class Function;
template <bool>
friend class MarkingVisitorBase;
- friend class SkippedCodeFunctions;
friend class StackFrame;
friend class Profiler;
friend class FunctionDeserializationCluster;
@@ -1415,7 +1408,6 @@
friend class StackFrame;
template <bool>
friend class MarkingVisitorBase;
- friend class SkippedCodeFunctions;
friend class Function;
friend class ImageReader;
friend class ImageWriter;
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index 4eac814..165aa3e 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -37,8 +37,6 @@
// Range of pointers to visit 'first' <= pointer <= 'last'.
virtual void VisitPointers(RawObject** first, RawObject** last) = 0;
- virtual bool visit_function_code() const { return true; }
- virtual void add_skipped_code_function(RawFunction* funct) { UNREACHABLE(); }
// len argument is the number of pointers to visit starting from 'p'.
void VisitPointers(RawObject** p, intptr_t len) {
VisitPointers(p, (p + len - 1));
diff --git a/tests/standalone_2/io/code_collection_test.dart b/tests/standalone_2/io/code_collection_test.dart
deleted file mode 100644
index 71f36b6..0000000
--- a/tests/standalone_2/io/code_collection_test.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2013, 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.
-
-// Dart test program testing code GC.
-
-import "package:expect/expect.dart";
-import "dart:async";
-import "dart:io";
-
-int foo(int x) {
- x = x + 1;
- // Print marker message while foo is on the stack so the code cannot be
- // collected.
- stderr.write("foo=$x\n");
- return x;
-}
-
-List<int> bar() {
- // A couple of big allocations trigger GC.
- var l = new List.filled(700000, 7);
- return l;
-}
-
-doTest() {
- var i = 0;
- var ret = foo(1); // Initial call to compile.
- // Time passes, GC runs, foo's code is dropped.
- var ms = const Duration(milliseconds: 100);
- var t = new Timer.periodic(ms, (timer) {
- i++;
- // Calling bar will trigger GC without foo being on the stack. This way
- // the method can be collected.
- bar();
- if (i > 1) {
- timer.cancel();
- // foo is called again to make sure we can still run it even after
- // its code has been detached.
- var ret = foo(2);
- // GC after here may collect the second compilation of foo.
- }
- });
-}
-
-List<String> packageOptions() {
- if (Platform.packageRoot != null) {
- return <String>['--package-root=${Platform.packageRoot}'];
- } else if (Platform.packageConfig != null) {
- return <String>['--packages=${Platform.packageConfig}'];
- } else {
- return <String>[];
- }
-}
-
-main(List<String> arguments) {
- if (arguments.contains("--run")) {
- doTest();
- } else {
- // Run the test and capture stderr.
- var args = packageOptions();
- args.addAll([
- "--verbose-gc",
- "--collect-code",
- "--code-collection-interval-in-us=0",
- "--old_gen_growth_rate=10",
- "--log-code-drop",
- "--optimization-counter-threshold=-1",
- Platform.script.toFilePath(),
- "--run"
- ]);
- print("+ ${Platform.executable} ${args.join(' ')}");
- var pr = Process.runSync(Platform.executable, args);
-
- print(pr.stderr);
- Expect.equals(0, pr.exitCode);
-
- // Code drops are logged with --log-code-drop. Look through stderr for the
- // message that foo's code was dropped.
- bool saw_foo2 = false;
- bool saw_detaching_foo = false;
- bool saw_foo3 = false;
- pr.stderr.split("\n").forEach((line) {
- if (line.contains("foo=2")) {
- Expect.isFalse(saw_foo2, "foo=2 ran twice");
- saw_foo2 = true;
- }
- if (line.contains("Detaching code") && line.contains("foo")) {
- Expect.isTrue(saw_foo2, "foo detached before running");
- // May detach twice.
- saw_detaching_foo = true;
- }
- if (line.contains("foo=3")) {
- Expect.isFalse(saw_foo3, "foo=3 ran twice");
- Expect.isTrue(saw_detaching_foo, "foo should have been collected");
- saw_foo3 = true;
- }
- });
-
- Expect.isTrue(saw_foo2, "Missing foo=2");
- Expect.isTrue(saw_detaching_foo, "Missing code collection for foo");
- Expect.isTrue(saw_foo3, "Missing foo=3");
- }
-}
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index ceb859a..5bece55 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -73,7 +73,6 @@
# The failures below still need to be investigated and possibly fixed, or marked as skipped.
[ $compiler == dartkb && $strong ]
-io/code_collection_test: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
io/dart_std_io_pipe_test: Pass, Timeout # Please triage
io/platform_resolved_executable_test/00: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
io/platform_resolved_executable_test/01: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
diff --git a/tests/standalone_2/standalone_2_precompiled.status b/tests/standalone_2/standalone_2_precompiled.status
index 64e4609..3209e7b 100644
--- a/tests/standalone_2/standalone_2_precompiled.status
+++ b/tests/standalone_2/standalone_2_precompiled.status
@@ -79,5 +79,4 @@
package/scenarios/packages_option_only/packages_option_only_test: Skip
[ $mode == product || $runtime == dart_precompiled ]
-io/code_collection_test: Skip # Incompatible flags
no_assert_test: SkipByDesign # Requires checked mode.
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index bc23a30..f6f03df 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -8,7 +8,6 @@
[ $compiler == app_jit ]
full_coverage_test: Skip # Platform.executable
-io/code_collection_test: Skip # Platform.executable
io/namespace_test: RuntimeError # Issue 33168
io/platform_resolved_executable_test/00: RuntimeError # Issue 33168
io/platform_resolved_executable_test/01: RuntimeError # Issue 33168
@@ -93,7 +92,6 @@
io/file_constructor_test: RuntimeError
[ $runtime == vm && ($arch == arm || $arch == arm64) ]
-io/code_collection_test: Timeout, Pass
io/dart_std_io_pipe_test: Timeout, Pass
io/file_input_stream_test: Skip # Issue 26109
io/file_stream_test: Skip # Issue 26109
@@ -101,7 +99,6 @@
io/process_sync_test: Timeout, Pass
[ $runtime == vm && ($arch == simarm || $arch == simarm64) ]
-io/code_collection_test: Timeout, Pass
io/dart_std_io_pipe_test: Timeout, Pass
io/http_client_stays_alive_test: Skip # Spawns process in Dart2 mode.
io/process_sync_test: Timeout, Pass