| Index: runtime/vm/raw_object.cc
|
| ===================================================================
|
| --- runtime/vm/raw_object.cc (revision 44996)
|
| +++ runtime/vm/raw_object.cc (working copy)
|
| @@ -399,7 +399,7 @@
|
| }
|
|
|
|
|
| -bool RawFunction::SkipCode(RawFunction* raw_fun) {
|
| +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
|
| @@ -409,20 +409,30 @@
|
| Function fn;
|
| fn = raw_fun;
|
|
|
| - Code code;
|
| - code = fn.CurrentCode();
|
| + // 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.HasCode() && // The function may not have code.
|
| - !fn.is_intrinsic() && // These may not increment the usage counter.
|
| - !code.is_optimized() &&
|
| - (fn.CurrentCode() == fn.unoptimized_code()) &&
|
| - !code.HasBreakpoint() &&
|
| - (fn.usage_counter() >= 0)) {
|
| + if (fn.usage_counter() >= 0) {
|
| fn.set_usage_counter(fn.usage_counter() / 2);
|
| - if (FLAG_always_drop_code || (fn.usage_counter() == 0)) {
|
| - return true;
|
| - }
|
| }
|
| + 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;
|
| }
|
|
|
| @@ -429,15 +439,25 @@
|
|
|
| intptr_t RawFunction::VisitFunctionPointers(RawFunction* raw_obj,
|
| ObjectPointerVisitor* visitor) {
|
| - if (visitor->visit_function_code() ||
|
| - !RawFunction::SkipCode(raw_obj)) {
|
| + if (visitor->visit_function_code() || !CheckUsageCounter(raw_obj)) {
|
| visitor->VisitPointers(raw_obj->from(), raw_obj->to());
|
| + return Function::InstanceSize();
|
| + }
|
| + visitor->VisitPointers(raw_obj->from(), raw_obj->to_no_code());
|
| +
|
| + if (ShouldVisitCode(raw_obj->ptr()->instructions_->ptr()->code_)) {
|
| + visitor->VisitPointer(
|
| + reinterpret_cast<RawObject**>(&raw_obj->ptr()->instructions_));
|
| } else {
|
| - GrowableArray<RawFunction*>* sfga = visitor->skipped_code_functions();
|
| - ASSERT(sfga != NULL);
|
| - sfga->Add(raw_obj);
|
| - visitor->VisitPointers(raw_obj->from(), raw_obj->to_no_code());
|
| + visitor->skipped_code_functions()->Add(raw_obj);
|
| }
|
| +
|
| + if (ShouldVisitCode(raw_obj->ptr()->unoptimized_code_)) {
|
| + visitor->VisitPointer(
|
| + reinterpret_cast<RawObject**>(&raw_obj->ptr()->unoptimized_code_));
|
| + } else {
|
| + visitor->skipped_code_functions()->Add(raw_obj);
|
| + }
|
| return Function::InstanceSize();
|
| }
|
|
|
|
|