Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: cherry-pick commits to be forward-compatible with V8 10.8 #44958

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.gypi
Expand Up @@ -36,7 +36,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.11',
'v8_embedder_string': '-node.15',

##### V8 defaults for Node.js #####

Expand Down
16 changes: 16 additions & 0 deletions deps/v8/include/js_protocol.pdl
Expand Up @@ -766,6 +766,22 @@ experimental domain HeapProfiler
# Average sample interval in bytes. Poisson distribution is used for the intervals. The
# default value is 32768 bytes.
optional number samplingInterval
# By default, the sampling heap profiler reports only objects which are
# still alive when the profile is returned via getSamplingProfile or
# stopSampling, which is useful for determining what functions contribute
# the most to steady-state memory usage. This flag instructs the sampling
# heap profiler to also include information about objects discarded by
# major GC, which will show which functions cause large temporary memory
# usage or long GC pauses.
optional boolean includeObjectsCollectedByMajorGC
# By default, the sampling heap profiler reports only objects which are
# still alive when the profile is returned via getSamplingProfile or
# stopSampling, which is useful for determining what functions contribute
# the most to steady-state memory usage. This flag instructs the sampling
# heap profiler to also include information about objects discarded by
# minor GC, which is useful when tuning a latency-sensitive application
# for minimal GC activity.
optional boolean includeObjectsCollectedByMinorGC

command startTrackingHeapObjects
parameters
Expand Down
12 changes: 0 additions & 12 deletions deps/v8/include/v8-platform.h
Expand Up @@ -943,18 +943,6 @@ class Platform {
*/
virtual void OnCriticalMemoryPressure() {}

/**
* Enables the embedder to respond in cases where V8 can't allocate large
* memory regions. The |length| parameter is the amount of memory needed.
* Returns true if memory is now available. Returns false if no memory could
* be made available. V8 will retry allocations until this method returns
* false.
*
* Embedder overrides of this function must NOT call back into V8.
*/
V8_DEPRECATED("Use the method without informative parameter")
virtual bool OnCriticalMemoryPressure(size_t length) { return false; }

/**
* Gets the number of worker threads used by
* Call(BlockingTask)OnWorkerThread(). This can be used to estimate the number
Expand Down
8 changes: 4 additions & 4 deletions deps/v8/include/v8-profiler.h
Expand Up @@ -903,6 +903,8 @@ class V8_EXPORT HeapProfiler {
enum SamplingFlags {
kSamplingNoFlags = 0,
kSamplingForceGC = 1 << 0,
kSamplingIncludeObjectsCollectedByMajorGC = 1 << 1,
kSamplingIncludeObjectsCollectedByMinorGC = 1 << 2,
};

/**
Expand Down Expand Up @@ -1097,10 +1099,8 @@ class V8_EXPORT HeapProfiler {
* |stack_depth| parameter controls the maximum number of stack frames to be
* captured on each allocation.
*
* NOTE: This is a proof-of-concept at this point. Right now we only sample
* newspace allocations. Support for paged space allocation (e.g. pre-tenured
* objects, large objects, code objects, etc.) and native allocations
* doesn't exist yet, but is anticipated in the future.
* NOTE: Support for native allocations doesn't exist yet, but is anticipated
* in the future.
*
* Objects allocated before the sampling is started will not be included in
* the profile.
Expand Down
10 changes: 9 additions & 1 deletion deps/v8/include/v8-script.h
Expand Up @@ -92,7 +92,15 @@ class V8_EXPORT UnboundScript {
* A compiled JavaScript module, not yet tied to a Context.
*/
class V8_EXPORT UnboundModuleScript : public Data {
// Only used as a container for code caching.
public:
/**
* Data read from magic sourceURL comments.
*/
Local<Value> GetSourceURL();
/**
* Data read from magic sourceMappingURL comments.
*/
Local<Value> GetSourceMappingURL();
};

/**
Expand Down
60 changes: 44 additions & 16 deletions deps/v8/src/api/api.cc
Expand Up @@ -1936,8 +1936,32 @@ void ObjectTemplate::SetCodeLike() {

// --- S c r i p t s ---

// Internally, UnboundScript is a SharedFunctionInfo, and Script is a
// JSFunction.
// Internally, UnboundScript and UnboundModuleScript are SharedFunctionInfos,
// and Script is a JSFunction.

namespace {
inline Local<Value> GetSharedFunctionInfoSourceMappingURL(
i::Isolate* isolate, i::Handle<i::SharedFunctionInfo> obj) {
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
if (obj->script().IsScript()) {
i::Object url = i::Script::cast(obj->script()).source_mapping_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
} else {
return Local<String>();
}
}

inline Local<Value> GetSharedFunctionInfoSourceURL(
i::Isolate* isolate, i::Handle<i::SharedFunctionInfo> obj) {
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
if (obj->script().IsScript()) {
i::Object url = i::Script::cast(obj->script()).source_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
} else {
return Local<String>();
}
}
} // namespace

ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
BufferPolicy buffer_policy_)
Expand Down Expand Up @@ -2022,28 +2046,32 @@ Local<Value> UnboundScript::GetSourceURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* i_isolate = obj->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
API_RCS_SCOPE(i_isolate, UnboundScript, GetSourceURL);
if (obj->script().IsScript()) {
i::Object url = i::Script::cast(obj->script()).source_url();
return Utils::ToLocal(i::Handle<i::Object>(url, i_isolate));
} else {
return Local<String>();
}
return GetSharedFunctionInfoSourceURL(i_isolate, obj);
}

Local<Value> UnboundScript::GetSourceMappingURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* i_isolate = obj->GetIsolate();
API_RCS_SCOPE(i_isolate, UnboundScript, GetSourceMappingURL);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
if (obj->script().IsScript()) {
i::Object url = i::Script::cast(obj->script()).source_mapping_url();
return Utils::ToLocal(i::Handle<i::Object>(url, i_isolate));
} else {
return Local<String>();
}
return GetSharedFunctionInfoSourceMappingURL(i_isolate, obj);
}

Local<Value> UnboundModuleScript::GetSourceURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* i_isolate = obj->GetIsolate();
API_RCS_SCOPE(i_isolate, UnboundModuleScript, GetSourceURL);
return GetSharedFunctionInfoSourceURL(i_isolate, obj);
}

Local<Value> UnboundModuleScript::GetSourceMappingURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* i_isolate = obj->GetIsolate();
API_RCS_SCOPE(i_isolate, UnboundModuleScript, GetSourceMappingURL);
return GetSharedFunctionInfoSourceMappingURL(i_isolate, obj);
}

MaybeLocal<Value> Script::Run(Local<Context> context) {
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/heap/heap.cc
Expand Up @@ -1819,6 +1819,8 @@ bool Heap::CollectGarbage(AllocationSpace space,

collector = SelectGarbageCollector(space, gc_reason, &collector_reason);

current_or_last_garbage_collector_ = collector;

if (collector == GarbageCollector::MARK_COMPACTOR &&
incremental_marking()->IsMinorMarking()) {
CollectGarbage(NEW_SPACE, GarbageCollectionReason::kFinalizeMinorMC);
Expand Down
6 changes: 6 additions & 0 deletions deps/v8/src/heap/heap.h
Expand Up @@ -1455,6 +1455,10 @@ class Heap {

bool is_current_gc_forced() const { return is_current_gc_forced_; }

GarbageCollector current_or_last_garbage_collector() const {
return current_or_last_garbage_collector_;
}

// Returns whether the currently in-progress GC should avoid increasing the
// ages on any objects that live for a set number of collections.
bool ShouldCurrentGCKeepAgesUnchanged() const {
Expand Down Expand Up @@ -2389,6 +2393,8 @@ class Heap {

bool is_current_gc_forced_ = false;
bool is_current_gc_for_heap_profiler_ = false;
GarbageCollector current_or_last_garbage_collector_ =
GarbageCollector::SCAVENGER;

ExternalStringTable external_string_table_;

Expand Down
26 changes: 23 additions & 3 deletions deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc
Expand Up @@ -29,6 +29,7 @@ static const char allocationTrackingEnabled[] = "allocationTrackingEnabled";
static const char samplingHeapProfilerEnabled[] = "samplingHeapProfilerEnabled";
static const char samplingHeapProfilerInterval[] =
"samplingHeapProfilerInterval";
static const char samplingHeapProfilerFlags[] = "samplingHeapProfilerFlags";
} // namespace HeapProfilerAgentState

class HeapSnapshotProgress final : public v8::ActivityControl {
Expand Down Expand Up @@ -208,7 +209,16 @@ void V8HeapProfilerAgentImpl::restore() {
double samplingInterval = m_state->doubleProperty(
HeapProfilerAgentState::samplingHeapProfilerInterval, -1);
DCHECK_GE(samplingInterval, 0);
startSampling(Maybe<double>(samplingInterval));
int flags = m_state->integerProperty(
HeapProfilerAgentState::samplingHeapProfilerFlags, 0);
startSampling(
Maybe<double>(samplingInterval),
Maybe<bool>(
flags &
v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC),
Maybe<bool>(
flags &
v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMinorGC));
}
}

Expand Down Expand Up @@ -387,7 +397,9 @@ void V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() {
}

Response V8HeapProfilerAgentImpl::startSampling(
Maybe<double> samplingInterval) {
Maybe<double> samplingInterval,
Maybe<bool> includeObjectsCollectedByMajorGC,
Maybe<bool> includeObjectsCollectedByMinorGC) {
v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler();
if (!profiler) return Response::ServerError("Cannot access v8 heap profiler");
const unsigned defaultSamplingInterval = 1 << 15;
Expand All @@ -400,9 +412,17 @@ Response V8HeapProfilerAgentImpl::startSampling(
samplingIntervalValue);
m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled,
true);
int flags = v8::HeapProfiler::kSamplingForceGC;
if (includeObjectsCollectedByMajorGC.fromMaybe(false)) {
flags |= v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC;
}
if (includeObjectsCollectedByMinorGC.fromMaybe(false)) {
flags |= v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMinorGC;
}
m_state->setInteger(HeapProfilerAgentState::samplingHeapProfilerFlags, flags);
profiler->StartSamplingHeapProfiler(
static_cast<uint64_t>(samplingIntervalValue), 128,
v8::HeapProfiler::kSamplingForceGC);
static_cast<v8::HeapProfiler::SamplingFlags>(flags));
return Response::Success();
}

Expand Down
4 changes: 3 additions & 1 deletion deps/v8/src/inspector/v8-heap-profiler-agent-impl.h
Expand Up @@ -56,7 +56,9 @@ class V8HeapProfilerAgentImpl : public protocol::HeapProfiler::Backend {
Response getHeapObjectId(const String16& objectId,
String16* heapSnapshotObjectId) override;

Response startSampling(Maybe<double> samplingInterval) override;
Response startSampling(Maybe<double> samplingInterval,
Maybe<bool> includeObjectsCollectedByMajorGC,
Maybe<bool> includeObjectsCollectedByMinorGC) override;
Response stopSampling(
std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfile>*) override;
Response getSamplingProfile(
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/logging/runtime-call-stats.h
Expand Up @@ -278,6 +278,8 @@ class RuntimeCallTimer final {
V(Uint32Array_New) \
V(Uint8Array_New) \
V(Uint8ClampedArray_New) \
V(UnboundModuleScript_GetSourceMappingURL) \
V(UnboundModuleScript_GetSourceURL) \
V(UnboundScript_GetColumnNumber) \
V(UnboundScript_GetId) \
V(UnboundScript_GetLineNumber) \
Expand Down
13 changes: 13 additions & 0 deletions deps/v8/src/profiler/sampling-heap-profiler.cc
Expand Up @@ -95,6 +95,19 @@ void SamplingHeapProfiler::SampleObject(Address soon_object, size_t size) {
void SamplingHeapProfiler::OnWeakCallback(
const WeakCallbackInfo<Sample>& data) {
Sample* sample = data.GetParameter();
Heap* heap = reinterpret_cast<Isolate*>(data.GetIsolate())->heap();
bool is_minor_gc =
heap->current_or_last_garbage_collector() == GarbageCollector::SCAVENGER;
bool should_keep_sample =
is_minor_gc
? (sample->profiler->flags_ &
v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMinorGC)
: (sample->profiler->flags_ &
v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC);
if (should_keep_sample) {
sample->global.Reset();
return;
}
AllocationNode* node = sample->owner;
DCHECK_GT(node->allocations_[sample->size], 0);
node->allocations_[sample->size]--;
Expand Down
53 changes: 39 additions & 14 deletions deps/v8/test/cctest/test-api.cc
Expand Up @@ -22920,33 +22920,58 @@ TEST(ScriptPositionInfo) {
}
}

void CheckMagicComments(v8::Isolate* isolate, Local<Script> script,
template <typename T>
void CheckMagicComments(v8::Isolate* isolate, Local<T> unbound_script,
const char* expected_source_url,
const char* expected_source_mapping_url) {
if (expected_source_url != nullptr) {
v8::String::Utf8Value url(isolate,
script->GetUnboundScript()->GetSourceURL());
v8::String::Utf8Value url(isolate, unbound_script->GetSourceURL());
CHECK_EQ(0, strcmp(expected_source_url, *url));
} else {
CHECK(script->GetUnboundScript()->GetSourceURL()->IsUndefined());
CHECK(unbound_script->GetSourceURL()->IsUndefined());
}
if (expected_source_mapping_url != nullptr) {
v8::String::Utf8Value url(
isolate, script->GetUnboundScript()->GetSourceMappingURL());
v8::String::Utf8Value url(isolate, unbound_script->GetSourceMappingURL());
CHECK_EQ(0, strcmp(expected_source_mapping_url, *url));
} else {
CHECK(script->GetUnboundScript()->GetSourceMappingURL()->IsUndefined());
CHECK(unbound_script->GetSourceMappingURL()->IsUndefined());
}
}

void SourceURLHelper(v8::Isolate* isolate, const char* source,
void SourceURLHelper(v8::Isolate* isolate, const char* source_text,
const char* expected_source_url,
const char* expected_source_mapping_url) {
Local<Script> script = v8_compile(source);
CheckMagicComments(isolate, script, expected_source_url,
expected_source_mapping_url);
}
// Check scripts
{
Local<Script> script = v8_compile(source_text);
CheckMagicComments(isolate, script->GetUnboundScript(), expected_source_url,
expected_source_mapping_url);
}

// Check modules
{
Local<v8::String> source_str = v8_str(source_text);
// Set a different resource name with the case above to invalidate the
// cache.
v8::ScriptOrigin origin(isolate,
v8_str("module.js"), // resource name
0, // line offset
0, // column offset
true, // is cross origin
-1, // script id
Local<Value>(), // source map URL
false, // is opaque
false, // is WASM
true // is ES Module
);
v8::ScriptCompiler::Source source(source_str, origin, nullptr);

Local<v8::Module> module =
v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
CheckMagicComments(isolate, module->GetUnboundModuleScript(),
expected_source_url, expected_source_mapping_url);
}
}

TEST(ScriptSourceURLAndSourceMappingURL) {
LocalContext env;
Expand Down Expand Up @@ -23245,8 +23270,8 @@ void RunStreamingTest(const char** chunks, v8::ScriptType type,
script.ToLocalChecked()->Run(env.local()).ToLocalChecked());
// All scripts are supposed to return the fixed value 13 when ran.
CHECK_EQ(13, result->Int32Value(env.local()).FromJust());
CheckMagicComments(isolate, script.ToLocalChecked(), expected_source_url,
expected_source_mapping_url);
CheckMagicComments(isolate, script.ToLocalChecked()->GetUnboundScript(),
expected_source_url, expected_source_mapping_url);
} else {
CHECK(script.IsEmpty());
}
Expand Down
@@ -0,0 +1,6 @@
Checks sampling heap profiler methods.
Retained size is less than 10KB: true
Including major GC increases size: true
Minor GC collected more: true
Total allocation is greater than 100KB: true
Successfully finished