blob: 576f82e2406f8e138f5ea6662076df9299ea550d [file] [log] [blame]
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include <algorithm>
#include "third_party/blink/public/platform/blame_context.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_node.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
#include "third_party/blink/renderer/core/dom/attr.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/buildflags.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
Node* V8GCController::OpaqueRootForGC(v8::Isolate*, Node* node) {
DCHECK(node);
if (node->isConnected())
return &node->GetDocument().TreeRootDocument();
if (auto* attr = DynamicTo<Attr>(node)) {
Node* owner_element = attr->ownerElement();
if (!owner_element)
return node;
node = owner_element;
}
while (Node* parent = node->ParentOrShadowHostOrTemplateHostNode())
node = parent;
return node;
}
#if !BUILDFLAG(USE_V8_OILPAN)
namespace {
bool IsNestedInV8GC(ThreadState* thread_state, v8::GCType type) {
return thread_state && (type == v8::kGCTypeMarkSweepCompact ||
type == v8::kGCTypeIncrementalMarking);
}
} // namespace
#endif // !USE_V8_OILPAN
void V8GCController::GcPrologue(v8::Isolate* isolate,
v8::GCType type,
v8::GCCallbackFlags flags) {
RUNTIME_CALL_TIMER_SCOPE(isolate, RuntimeCallStats::CounterId::kGcPrologue);
#if !BUILDFLAG(USE_V8_OILPAN)
ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
IsNestedInV8GC(ThreadState::Current(), type)
? ThreadState::Current()->Heap().stats_collector()
: nullptr);
#endif // !USE_V8_OILPAN
auto* per_isolate_data = V8PerIsolateData::From(isolate);
per_isolate_data->EnterGC();
ScriptForbiddenScope::Enter();
// Attribute garbage collection to the all frames instead of a specific
// frame.
if (BlameContext* blame_context =
Platform::Current()->GetTopLevelBlameContext())
blame_context->Enter();
v8::HandleScope scope(isolate);
switch (type) {
case v8::kGCTypeIncrementalMarking:
// Recomputing ASWs is opportunistic during incremental marking as they
// only need to be recomputing during the atomic pause for corectness.
per_isolate_data->GetActiveScriptWrappableManager()
->RecomputeActiveScriptWrappables(
ActiveScriptWrappableManager::RecomputeMode::kOpportunistic);
break;
case v8::kGCTypeMarkSweepCompact:
per_isolate_data->GetActiveScriptWrappableManager()
->RecomputeActiveScriptWrappables(
ActiveScriptWrappableManager::RecomputeMode::kRequired);
break;
default:
break;
}
}
void V8GCController::GcEpilogue(v8::Isolate* isolate,
v8::GCType type,
v8::GCCallbackFlags flags) {
RUNTIME_CALL_TIMER_SCOPE(isolate, RuntimeCallStats::CounterId::kGcEpilogue);
#if !BUILDFLAG(USE_V8_OILPAN)
ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
IsNestedInV8GC(ThreadState::Current(), type)
? ThreadState::Current()->Heap().stats_collector()
: nullptr);
#endif // !USE_V8_OILPAN
V8PerIsolateData::From(isolate)->LeaveGC();
ScriptForbiddenScope::Exit();
if (BlameContext* blame_context =
Platform::Current()->GetTopLevelBlameContext())
blame_context->Leave();
ThreadState* current_thread_state = ThreadState::Current();
if (current_thread_state) {
current_thread_state->NotifyGarbageCollection(type, flags);
}
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
"UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data",
inspector_update_counters_event::Data());
}
} // namespace blink