mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1896505 - Track Promise Type II subclassing r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D210536
This commit is contained in:
parent
a906e69d18
commit
9942bafee7
@ -71,6 +71,7 @@ custom JS_asmjs uses asm.js
|
||||
custom JS_wasm uses WebAssembly
|
||||
custom JS_wasm_legacy_exceptions uses WebAssembly legacy exception-handling
|
||||
custom JS_subclassing_array_type_2 Array is Type II subclassed
|
||||
custom JS_subclassing_promise_type_2 Promise is Type II subclassed
|
||||
|
||||
// Console API
|
||||
method console.assert
|
||||
|
@ -107,8 +107,8 @@ use.counter:
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
# Total of 2311 use counter metrics (excludes denominators).
|
||||
# Total of 355 'page' use counters.
|
||||
# Total of 2313 use counter metrics (excludes denominators).
|
||||
# Total of 356 'page' use counters.
|
||||
use.counter.page:
|
||||
svgsvgelement_getelementbyid:
|
||||
type: counter
|
||||
@ -552,6 +552,23 @@ use.counter.page:
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
js_subclassing_promise_type_2:
|
||||
type: counter
|
||||
description: >
|
||||
Whether a page Promise is Type II subclassed.
|
||||
Compare against `use.counter.top_level_content_documents_destroyed`
|
||||
to calculate the rate.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
console_assert:
|
||||
type: counter
|
||||
description: >
|
||||
@ -6145,7 +6162,7 @@ use.counter.page:
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
# Total of 355 'document' use counters.
|
||||
# Total of 356 'document' use counters.
|
||||
use.counter.doc:
|
||||
svgsvgelement_getelementbyid:
|
||||
type: counter
|
||||
@ -6589,6 +6606,23 @@ use.counter.doc:
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
js_subclassing_promise_type_2:
|
||||
type: counter
|
||||
description: >
|
||||
Whether a document Promise is Type II subclassed.
|
||||
Compare against `use.counter.content_documents_destroyed`
|
||||
to calculate the rate.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
console_assert:
|
||||
type: counter
|
||||
description: >
|
||||
|
@ -84,11 +84,12 @@ using JSAccumulateTelemetryDataCallback = void (*)(JSMetric, uint32_t);
|
||||
extern JS_PUBLIC_API void JS_SetAccumulateTelemetryCallback(
|
||||
JSContext* cx, JSAccumulateTelemetryDataCallback callback);
|
||||
|
||||
#define FOR_EACH_JS_USE_COUNTER(_) \
|
||||
_(ASMJS, AsmJS) \
|
||||
_(WASM, Wasm) \
|
||||
_(WASM_LEGACY_EXCEPTIONS, WasmLegacyExceptions) \
|
||||
_(SUBCLASSING_ARRAY_TYPE_II, SubclassingArrayTypeII)
|
||||
#define FOR_EACH_JS_USE_COUNTER(_) \
|
||||
_(ASMJS, AsmJS) \
|
||||
_(WASM, Wasm) \
|
||||
_(WASM_LEGACY_EXCEPTIONS, WasmLegacyExceptions) \
|
||||
_(SUBCLASSING_ARRAY_TYPE_II, SubclassingArrayTypeII) \
|
||||
_(SUBCLASSING_PROMISE_TYPE_II, SubclassingPromiseTypeII)
|
||||
|
||||
/*
|
||||
* Use counter names passed to the accumulate use counter callback.
|
||||
|
@ -1802,6 +1802,9 @@ CreatePromiseObjectWithoutResolutionFunctions(JSContext* cx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// At this point this is effectively subclassing;
|
||||
ReportUsageCounter(cx, C, SUBCLASSING_PROMISE, SUBCLASSING_TYPE_II);
|
||||
|
||||
// Step 4. Let executorClosure be a new Abstract Closure with parameters
|
||||
// (resolve, reject) that captures promiseCapability and performs the
|
||||
// following steps when called:
|
||||
@ -2791,6 +2794,12 @@ static bool PromiseConstructor(JSContext* cx, unsigned argc, Value* vp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool js::IsPromiseConstructor(const JSObject* obj) {
|
||||
// Note: this also returns true for cross-realm Promise constructors in the
|
||||
// same compartment.
|
||||
return IsNativeFunction(obj, PromiseConstructor);
|
||||
}
|
||||
|
||||
/**
|
||||
* ES2022 draft rev d03c1ec6e235a5180fa772b6178727c17974cb14
|
||||
*
|
||||
|
@ -263,6 +263,7 @@ bool IsPromiseWithDefaultResolvingFunction(PromiseObject* promise);
|
||||
void SetAlreadyResolvedPromiseWithDefaultResolvingFunction(
|
||||
PromiseObject* promise);
|
||||
|
||||
bool IsPromiseConstructor(const JSObject* obj);
|
||||
} // namespace js
|
||||
|
||||
#endif // builtin_Promise_h
|
||||
|
@ -130,7 +130,8 @@
|
||||
|
||||
// Support for usage counters around subclassing:
|
||||
#define SUBCLASSING_ARRAY 1
|
||||
#define SUBCLASSING_LAST_BUILTIN 2
|
||||
#define SUBCLASSING_PROMISE 2
|
||||
#define SUBCLASSING_LAST_BUILTIN 3
|
||||
|
||||
#define SUBCLASSING_TYPE_II 2
|
||||
#define SUBCLASSING_TYPE_III 3
|
||||
@ -141,5 +142,7 @@
|
||||
#define SUBCLASSING_BUILTIN_SHIFT 16
|
||||
#define SUBCLASS_ARRAY_TYPE_II \
|
||||
((SUBCLASSING_ARRAY << SUBCLASSING_BUILTIN_SHIFT) | SUBCLASSING_TYPE_II)
|
||||
#define SUBCLASS_PROMISE_TYPE_II \
|
||||
((SUBCLASSING_PROMISE << SUBCLASSING_BUILTIN_SHIFT) | SUBCLASSING_TYPE_II)
|
||||
|
||||
#endif
|
||||
|
90
js/src/jit-test/tests/use-counters/promise-counters.js
Normal file
90
js/src/jit-test/tests/use-counters/promise-counters.js
Normal file
@ -0,0 +1,90 @@
|
||||
function test_function_for_use_counter_integration(fn, counter, expected_growth = true) {
|
||||
let before = getUseCounterResults();
|
||||
assertEq(counter in before, true);
|
||||
|
||||
fn();
|
||||
|
||||
let after = getUseCounterResults();
|
||||
if (expected_growth) {
|
||||
console.log("Yes Increase: Before ", before[counter], " After", after[counter]);
|
||||
assertEq(after[counter] > before[counter], true);
|
||||
} else {
|
||||
console.log("No Increase: Before ", before[counter], " After", after[counter]);
|
||||
assertEq(after[counter] == before[counter], true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MyPromise extends Promise { }
|
||||
|
||||
function promise_all() {
|
||||
let p = Promise.all([Promise.resolve(1)]);
|
||||
assertEq(p instanceof Promise, true);
|
||||
}
|
||||
function promise_all_subclassing_type_ii() {
|
||||
let p = MyPromise.all([Promise.resolve(1)]);
|
||||
assertEq(p instanceof MyPromise, true);
|
||||
}
|
||||
|
||||
test_function_for_use_counter_integration(promise_all, "SubclassingPromiseTypeII", /* expected_growth = */ false);
|
||||
test_function_for_use_counter_integration(promise_all_subclassing_type_ii, "SubclassingPromiseTypeII", /* expected_growth = */ true);
|
||||
|
||||
function promise_allSettled() {
|
||||
let p = Promise.allSettled([Promise.resolve(1)]);
|
||||
assertEq(p instanceof Promise, true);
|
||||
}
|
||||
function promise_allSettled_subclassing_type_ii() {
|
||||
let p = MyPromise.allSettled([Promise.resolve(1)]);
|
||||
assertEq(p instanceof MyPromise, true);
|
||||
}
|
||||
|
||||
test_function_for_use_counter_integration(promise_allSettled, "SubclassingPromiseTypeII", /* expected_growth = */ false);
|
||||
test_function_for_use_counter_integration(promise_allSettled_subclassing_type_ii, "SubclassingPromiseTypeII", /* expected_growth = */ true);
|
||||
|
||||
function promise_any() {
|
||||
let p = Promise.any([Promise.resolve(1)]);
|
||||
assertEq(p instanceof Promise, true);
|
||||
}
|
||||
function promise_any_subclassing_type_ii() {
|
||||
let p = MyPromise.any([Promise.resolve(1)]);
|
||||
assertEq(p instanceof MyPromise, true);
|
||||
}
|
||||
|
||||
test_function_for_use_counter_integration(promise_any, "SubclassingPromiseTypeII", /* expected_growth = */ false);
|
||||
test_function_for_use_counter_integration(promise_any_subclassing_type_ii, "SubclassingPromiseTypeII", /* expected_growth = */ true);
|
||||
|
||||
function promise_race() {
|
||||
let p = Promise.race([Promise.resolve(1)]);
|
||||
assertEq(p instanceof Promise, true);
|
||||
}
|
||||
function promise_race_subclassing_type_ii() {
|
||||
let p = MyPromise.race([Promise.resolve(1)]);
|
||||
assertEq(p instanceof MyPromise, true);
|
||||
}
|
||||
|
||||
test_function_for_use_counter_integration(promise_race, "SubclassingPromiseTypeII", /* expected_growth = */ false);
|
||||
test_function_for_use_counter_integration(promise_race_subclassing_type_ii, "SubclassingPromiseTypeII", /* expected_growth = */ true);
|
||||
|
||||
function promise_resolve() {
|
||||
let p = Promise.resolve(1)
|
||||
assertEq(p instanceof Promise, true);
|
||||
}
|
||||
function promise_resolve_subclassing_type_ii() {
|
||||
let p = MyPromise.resolve(1)
|
||||
assertEq(p instanceof MyPromise, true);
|
||||
}
|
||||
|
||||
test_function_for_use_counter_integration(promise_resolve, "SubclassingPromiseTypeII", /* expected_growth = */ false);
|
||||
test_function_for_use_counter_integration(promise_resolve_subclassing_type_ii, "SubclassingPromiseTypeII", /* expected_growth = */ true);
|
||||
|
||||
function promise_reject() {
|
||||
let p = Promise.reject(1).catch(() => undefined)
|
||||
assertEq(p instanceof Promise, true);
|
||||
}
|
||||
function promise_reject_subclassing_type_ii() {
|
||||
let p = MyPromise.reject(1).catch(() => undefined)
|
||||
assertEq(p instanceof MyPromise, true);
|
||||
}
|
||||
|
||||
test_function_for_use_counter_integration(promise_reject, "SubclassingPromiseTypeII", /* expected_growth = */ false);
|
||||
test_function_for_use_counter_integration(promise_reject_subclassing_type_ii, "SubclassingPromiseTypeII", /* expected_growth = */ true);
|
@ -2966,13 +2966,8 @@ bool js::ReportUsageCounter(JSContext* cx, HandleObject constructor,
|
||||
switch (builtin) {
|
||||
case SUBCLASSING_ARRAY: {
|
||||
// Check if the provided function is actually the array constructor
|
||||
// anyhow; We're interested in if the object is in the current realm; CCW
|
||||
// realm is OK because even if this is a CCW it'll fail the
|
||||
// IsArrayConstructor check.
|
||||
//
|
||||
// Constructor may be nullptr if check has already been done.
|
||||
if (constructor && IsArrayConstructor(constructor) &&
|
||||
constructor->maybeCCWRealm() == cx->realm()) {
|
||||
// anyhow; Constructor may be nullptr if check has already been done.
|
||||
if (constructor && IsArrayConstructor(constructor)) {
|
||||
return true;
|
||||
}
|
||||
switch (type) {
|
||||
@ -2984,6 +2979,19 @@ bool js::ReportUsageCounter(JSContext* cx, HandleObject constructor,
|
||||
MOZ_CRASH("Unexpected Subclassing Type");
|
||||
}
|
||||
}
|
||||
case SUBCLASSING_PROMISE: {
|
||||
if (constructor && IsPromiseConstructor(constructor)) {
|
||||
return true;
|
||||
}
|
||||
switch (type) {
|
||||
case SUBCLASSING_TYPE_II:
|
||||
cx->runtime()->setUseCounter(
|
||||
cx->global(), JSUseCounter::SUBCLASSING_PROMISE_TYPE_II);
|
||||
return true;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected Subclassing Type");
|
||||
}
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unexpected builtin");
|
||||
};
|
||||
@ -3007,9 +3015,13 @@ bool js::ReportUsageCounter(JSContext* cx, HandleObject constructor,
|
||||
//
|
||||
// This produces the following magic constant values:
|
||||
//
|
||||
// Array Subclassing Type II: (1 << 16) | 2 == 0x010002
|
||||
// Array Subclassing Type III: (1 << 16) | 3 == 0x010003
|
||||
// Array Subclassing Type IV: (1 << 16) | 4 == 0x010004
|
||||
// Array Subclassing Type II: (1 << 16) | 2 == 0x010002
|
||||
// Array Subclassing Type III: (1 << 16) | 3 == 0x010003
|
||||
// Array Subclassing Type IV: (1 << 16) | 4 == 0x010000
|
||||
//
|
||||
// Promise Subclassing Type II: (2 << 16) | 2 == 0x020002
|
||||
// Promise Subclassing Type III: (2 << 16) | 3 == 0x020003
|
||||
// Promise Subclassing Type IV: (2 << 16) | 4 == 0x020004
|
||||
//
|
||||
// Subclassing is reported iff the constructor provided doesn't match
|
||||
// the existing prototype.
|
||||
|
@ -2639,6 +2639,10 @@ static void SetUseCounterCallback(JSObject* obj, JSUseCounter counter) {
|
||||
SetUseCounter(obj,
|
||||
mozilla::eUseCounter_custom_JS_subclassing_array_type_2);
|
||||
return;
|
||||
case JSUseCounter::SUBCLASSING_PROMISE_TYPE_II:
|
||||
SetUseCounter(obj,
|
||||
mozilla::eUseCounter_custom_JS_subclassing_promise_type_2);
|
||||
return;
|
||||
case JSUseCounter::COUNT:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user