Commit 535c5053 authored by Natalie Silvanovich's avatar Natalie Silvanovich Committed by Commit Bot

Adding counters for elements on Array.prototype and Object.prototype

Bug: chromium:1048354
Change-Id: Ib37c33f918e96b100926b8247a2ca034482fb978
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2028840
Commit-Queue: Natalie Silvanovich <natashenka@google.com>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66092}
parent bd02f663
......@@ -8430,6 +8430,8 @@ class V8_EXPORT Isolate {
kRegExpReplaceCalledOnSlowRegExp = 80,
kDisplayNames = 81,
kSharedArrayBufferConstructed = 82,
kArrayPrototypeHasElements = 83,
kObjectPrototypeHasElements = 84,
// If you add new values here, you'll also need to update Chromium's:
// web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to
......
......@@ -10,7 +10,9 @@
#include <fstream> // NOLINT(readability/streams)
#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>
#include <utility>
#include "src/api/api-inl.h"
#include "src/ast/ast-value-factory.h"
......@@ -3755,18 +3757,21 @@ void Isolate::set_date_cache(DateCache* date_cache) {
date_cache_ = date_cache;
}
bool Isolate::IsArrayOrObjectOrStringPrototype(Object object) {
Isolate::KnownPrototype Isolate::IsArrayOrObjectOrStringPrototype(
Object object) {
Object context = heap()->native_contexts_list();
while (!context.IsUndefined(this)) {
Context current_context = Context::cast(context);
if (current_context.initial_object_prototype() == object ||
current_context.initial_array_prototype() == object ||
current_context.initial_string_prototype() == object) {
return true;
if (current_context.initial_object_prototype() == object) {
return KnownPrototype::kObject;
} else if (current_context.initial_array_prototype() == object) {
return KnownPrototype::kArray;
} else if (current_context.initial_string_prototype() == object) {
return KnownPrototype::kString;
}
context = current_context.next_context_link();
}
return false;
return KnownPrototype::kNone;
}
bool Isolate::IsInAnyContext(Object object, uint32_t index) {
......@@ -3786,7 +3791,13 @@ void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) {
DisallowHeapAllocation no_gc;
if (!object->map().is_prototype_map()) return;
if (!Protectors::IsNoElementsIntact(this)) return;
if (!IsArrayOrObjectOrStringPrototype(*object)) return;
KnownPrototype obj_type = IsArrayOrObjectOrStringPrototype(*object);
if (obj_type == KnownPrototype::kNone) return;
if (obj_type == KnownPrototype::kObject) {
this->CountUsage(v8::Isolate::kObjectPrototypeHasElements);
} else if (obj_type == KnownPrototype::kArray) {
this->CountUsage(v8::Isolate::kArrayPrototypeHasElements);
}
Protectors::InvalidateNoElements(this);
}
......
......@@ -1169,7 +1169,9 @@ class Isolate final : private HiddenFactory {
#endif // V8_INTL_SUPPORT
bool IsArrayOrObjectOrStringPrototype(Object object);
enum class KnownPrototype { kNone, kObject, kArray, kString };
KnownPrototype IsArrayOrObjectOrStringPrototype(Object object);
// On intent to set an element in object, make sure that appropriate
// notifications occur if the set is on the elements of the array or
......
......@@ -115,6 +115,42 @@ TEST(RegExpMatchIsFalseishOnJSRegExp) {
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp]);
}
TEST(ObjectPrototypeHasElements) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
global_use_counts = use_counts;
CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
CompileRun("var o = {}; o[1] = 2;");
CHECK_EQ(0, use_counts[v8::Isolate::kObjectPrototypeHasElements]);
CompileRun("var o = {}; var p = {}; o.__proto__ = p; p[1] = 2;");
CHECK_EQ(0, use_counts[v8::Isolate::kObjectPrototypeHasElements]);
CompileRun("Object.prototype[1] = 2;");
CHECK_EQ(1, use_counts[v8::Isolate::kObjectPrototypeHasElements]);
}
TEST(ArrayPrototypeHasElements) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
global_use_counts = use_counts;
CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
CompileRun("var a = []; a[1] = 2;");
CHECK_EQ(0, use_counts[v8::Isolate::kArrayPrototypeHasElements]);
CompileRun("var a = []; var p = []; a.__proto__ = p; p[1] = 2;");
CHECK_EQ(0, use_counts[v8::Isolate::kArrayPrototypeHasElements]);
CompileRun("Array.prototype[1] = 2;");
CHECK_EQ(1, use_counts[v8::Isolate::kArrayPrototypeHasElements]);
}
} // namespace test_usecounters
} // namespace internal
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment