[class] use KeyedDefineOwnIC in private brand initialization

This improves the performance of initializing instances with
private methods by 5-6x and makes it on par with initializing
instances with only public methods.

Drive-by: remove the obsolete AddPrivateField runtime function
along with the AddPrivateBrand function.

Bug: v8:10793, v8:12355
Change-Id: Ic0896adb2102db7790f955fecbdd22f61ab2e7ad
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3256999
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77664}
This commit is contained in:
Joyee Cheung 2021-11-03 00:41:01 +08:00 committed by V8 LUCI CQ
parent 91765804e3
commit 7083b10bb1
7 changed files with 117 additions and 173 deletions

View File

@ -451,10 +451,11 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name,
LookupForRead(&it, IsAnyHas());
if (name->IsPrivate()) {
if (!IsAnyHas() && name->IsPrivateName() && !it.IsFound()) {
Handle<String> name_string(
String::cast(Symbol::cast(*name).description()), isolate());
if (name->IsPrivateBrand()) {
Handle<Symbol> private_symbol = Handle<Symbol>::cast(name);
if (!IsAnyHas() && private_symbol->is_private_name() && !it.IsFound()) {
Handle<String> name_string(String::cast(private_symbol->description()),
isolate());
if (private_symbol->is_private_brand()) {
Handle<String> class_name =
(name_string->length() == 0)
? isolate()->factory()->anonymous_string()
@ -1767,8 +1768,11 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
Handle<String> name_string(
String::cast(Symbol::cast(*name).description()), isolate());
if (exists) {
return TypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
object, name_string);
MessageTemplate message =
name->IsPrivateBrand()
? MessageTemplate::kInvalidPrivateBrandReinitialization
: MessageTemplate::kInvalidPrivateFieldReinitialization;
return TypeError(message, object, name_string);
} else {
return TypeError(MessageTemplate::kInvalidPrivateMemberWrite, object,
name_string);

View File

@ -2843,17 +2843,17 @@ void BytecodeGenerator::BuildInvalidPropertyAccess(MessageTemplate tmpl,
}
void BytecodeGenerator::BuildPrivateBrandInitialization(Register receiver) {
RegisterList brand_args = register_allocator()->NewRegisterList(3);
Variable* brand = info()->scope()->outer_scope()->AsClassScope()->brand();
int depth = execution_context()->ContextChainDepth(brand->scope());
ContextScope* class_context = execution_context()->Previous(depth);
BuildVariableLoad(brand, HoleCheckMode::kElided);
Register brand_reg = register_allocator()->NewRegister();
FeedbackSlot slot = feedback_spec()->AddKeyedDefineOwnICSlot();
builder()
->StoreAccumulatorInRegister(brand_args[1])
.MoveRegister(receiver, brand_args[0])
.MoveRegister(class_context->reg(), brand_args[2])
.CallRuntime(Runtime::kAddPrivateBrand, brand_args);
->StoreAccumulatorInRegister(brand_reg)
.LoadAccumulatorWithRegister(class_context->reg())
.DefineKeyedProperty(receiver, brand_reg, feedback_index(slot));
}
void BytecodeGenerator::BuildInstanceMemberInitialization(Register constructor,

View File

@ -566,13 +566,14 @@ MaybeHandle<Object> Runtime::DefineObjectOwnProperty(
LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN);
if (it.IsFound() && key->IsSymbol() && Symbol::cast(*key).is_private_name()) {
Handle<Object> name_string(Symbol::cast(*key).description(), isolate);
Handle<Symbol> private_symbol = Handle<Symbol>::cast(key);
Handle<Object> name_string(private_symbol->description(), isolate);
DCHECK(name_string->IsString());
THROW_NEW_ERROR(
isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
name_string),
Object);
MessageTemplate message =
private_symbol->is_private_brand()
? MessageTemplate::kInvalidPrivateBrandReinitialization
: MessageTemplate::kInvalidPrivateFieldReinitialization;
THROW_NEW_ERROR(isolate, NewTypeError(message, name_string), Object);
}
MAYBE_RETURN_NULL(
@ -1442,54 +1443,6 @@ RUNTIME_FUNCTION(Runtime_CreatePrivateAccessors) {
return *pair;
}
RUNTIME_FUNCTION(Runtime_AddPrivateBrand) {
HandleScope scope(isolate);
DCHECK_EQ(args.length(), 3);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(Symbol, brand, 1);
CONVERT_ARG_HANDLE_CHECKED(Context, context, 2);
DCHECK(brand->is_private_name());
LookupIterator it(isolate, receiver, brand, LookupIterator::OWN);
if (it.IsFound()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kInvalidPrivateBrandReinitialization,
brand));
}
PropertyAttributes attributes =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
CHECK(Object::AddDataProperty(&it, context, attributes, Just(kDontThrow),
StoreOrigin::kMaybeKeyed)
.FromJust());
return *receiver;
}
RUNTIME_FUNCTION(Runtime_AddPrivateField) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0);
CONVERT_ARG_HANDLE_CHECKED(Symbol, key, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
DCHECK(key->is_private_name());
LookupIterator it(isolate, o, key, LookupIterator::OWN);
if (it.IsFound()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
key));
}
CHECK(Object::AddDataProperty(&it, value, NONE, Just(kDontThrow),
StoreOrigin::kMaybeKeyed)
.FromJust());
return ReadOnlyRoots(isolate).undefined_value();
}
// TODO(v8:11330) This is only here while the CSA/Torque implementaton of
// SwissNameDictionary is work in progress.
RUNTIME_FUNCTION(Runtime_SwissTableAllocate) {

View File

@ -104,8 +104,6 @@ bool Runtime::NeedsExactContext(FunctionId id) {
// us to usually eliminate the catch context for the implicit
// try-catch in async function.
return false;
case Runtime::kAddPrivateField:
case Runtime::kAddPrivateBrand:
case Runtime::kCreatePrivateAccessors:
case Runtime::kCopyDataProperties:
case Runtime::kCreateDataProperty:

View File

@ -287,8 +287,6 @@ namespace internal {
#define FOR_EACH_INTRINSIC_OBJECT(F, I) \
F(AddDictionaryProperty, 3, 1) \
F(AddPrivateField, 3, 1) \
F(AddPrivateBrand, 3, 1) \
F(AllocateHeapNumber, 0, 1) \
F(CollectTypeProfile, 3, 1) \
F(CompleteInobjectSlackTrackingForMap, 1, 1) \

View File

@ -21,43 +21,42 @@ snippet: "
var test = A;
new test;
"
frame size: 7
frame size: 5
parameter count: 1
bytecode array length: 87
bytecode array length: 82
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 67 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 67 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 76 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star4),
B(Star2),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 81 E> */ B(LdaKeyedProperty), R(this), U8(0),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1),
B(Star5),
B(CallProperty0), R(5), R(this), U8(2),
B(Inc), U8(4),
B(Star5),
/* 83 E> */ B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(4), U8(1),
B(Star6),
B(CallProperty1), R(6), R(this), R(5), U8(5),
/* 91 S> */ B(LdaSmi), I8(1),
/* 81 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(2), U8(1),
B(Star3),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star5),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 96 E> */ B(LdaKeyedProperty), R(this), U8(7),
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(5), U8(1),
B(Star6),
B(CallProperty1), R(6), R(this), R(3), U8(9),
/* 108 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(CallProperty0), R(3), R(this), U8(4),
B(Inc), U8(6),
B(Star3),
/* 83 E> */ B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), U8(1),
B(Star4),
B(CallProperty1), R(4), R(this), R(3), U8(7),
/* 91 S> */ B(LdaSmi), I8(1),
B(Star1),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star3),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 120 E> */ B(LdaKeyedProperty), R(this), U8(11),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1),
B(Star5),
B(CallProperty0), R(5), R(this), U8(13),
/* 96 E> */ B(LdaKeyedProperty), R(this), U8(9),
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(3), U8(1),
B(Star4),
B(CallProperty1), R(4), R(this), R(1), U8(11),
/* 108 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star2),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 120 E> */ B(LdaKeyedProperty), R(this), U8(13),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(2), U8(1),
B(Star3),
B(CallProperty0), R(3), R(this), U8(15),
/* 123 S> */ B(Return),
]
constant pool: [
@ -74,20 +73,19 @@ snippet: "
var test = B;
new test;
"
frame size: 5
frame size: 3
parameter count: 1
bytecode array length: 28
bytecode array length: 23
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 48 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 48 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 53 S> */ B(Wide), B(LdaSmi), I16(285),
B(Star3),
B(Star1),
B(LdaConstant), U8(0),
B(Star4),
B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
B(Star2),
B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
]
constant pool: [
@ -105,20 +103,19 @@ snippet: "
var test = C;
new test;
"
frame size: 5
frame size: 3
parameter count: 1
bytecode array length: 28
bytecode array length: 23
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 41 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 41 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 46 S> */ B(Wide), B(LdaSmi), I16(284),
B(Star3),
B(Star1),
B(LdaConstant), U8(0),
B(Star4),
B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
B(Star2),
B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
]
constant pool: [
@ -136,20 +133,19 @@ snippet: "
var test = D;
new test;
"
frame size: 5
frame size: 3
parameter count: 1
bytecode array length: 28
bytecode array length: 23
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 48 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 48 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 53 S> */ B(Wide), B(LdaSmi), I16(285),
B(Star3),
B(Star1),
B(LdaConstant), U8(0),
B(Star4),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
B(Star2),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
]
constant pool: [
@ -167,20 +163,19 @@ snippet: "
var test = E;
new test;
"
frame size: 6
frame size: 4
parameter count: 1
bytecode array length: 28
bytecode array length: 23
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 41 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 41 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 46 S> */ B(Wide), B(LdaSmi), I16(284),
B(Star4),
B(Star2),
B(LdaConstant), U8(0),
B(Star5),
B(CallRuntime), U16(Runtime::kNewTypeError), R(4), U8(2),
B(Star3),
B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
]
constant pool: [

View File

@ -16,20 +16,19 @@ snippet: "
var test = A;
new A;
"
frame size: 4
frame size: 2
parameter count: 1
bytecode array length: 28
bytecode array length: 23
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 44 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 61 E> */ B(LdaKeyedProperty), R(this), U8(0),
/* 61 E> */ B(LdaKeyedProperty), R(this), U8(2),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star3),
/* 63 E> */ B(CallAnyReceiver), R(3), R(this), U8(1), U8(2),
B(Star1),
/* 63 E> */ B(CallAnyReceiver), R(1), R(this), U8(1), U8(4),
/* 66 S> */ B(Return),
]
constant pool: [
@ -47,20 +46,19 @@ snippet: "
var test = B;
new test;
"
frame size: 5
frame size: 3
parameter count: 1
bytecode array length: 28
bytecode array length: 23
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 44 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 49 S> */ B(Wide), B(LdaSmi), I16(283),
B(Star3),
B(Star1),
B(LdaConstant), U8(0),
B(Star4),
/* 57 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
B(Star2),
/* 57 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
]
constant pool: [
@ -79,20 +77,19 @@ snippet: "
var test = C;
new test;
"
frame size: 5
frame size: 3
parameter count: 1
bytecode array length: 28
bytecode array length: 23
bytecodes: [
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
B(Star0),
B(Ldar), R(context),
/* 44 E> */ B(StaKeyedPropertyAsDefine), R(this), R(0), U8(0),
/* 49 S> */ B(Wide), B(LdaSmi), I16(283),
B(Star3),
B(Star1),
B(LdaConstant), U8(0),
B(Star4),
B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
B(Star2),
B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
]
constant pool: [
@ -111,28 +108,27 @@ snippet: "
var test = D;
new test;
"
frame size: 6
frame size: 4
parameter count: 1
bytecode array length: 53
bytecode array length: 48
bytecodes: [
/* 44 E> */ B(CreateFunctionContext), U8(0), U8(1),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(2),
B(LdaImmutableContextSlot), R(0), U8(3), U8(0),
B(Star2),
B(Mov), R(this), R(1),
B(Mov), R(0), R(3),
B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(1), U8(3),
B(Star1),
B(Ldar), R(0),
B(StaKeyedPropertyAsDefine), R(this), R(1), U8(0),
/* 49 S> */ B(CreateClosure), U8(1), U8(0), U8(2),
B(Star5),
/* 61 E> */ B(CallUndefinedReceiver0), R(5), U8(0),
B(Star5),
B(Star3),
/* 61 E> */ B(CallUndefinedReceiver0), R(3), U8(2),
B(Star3),
B(LdaImmutableContextSlot), R(0), U8(3), U8(0),
/* 63 E> */ B(LdaKeyedProperty), R(5), U8(2),
/* 63 E> */ B(LdaKeyedProperty), R(3), U8(4),
B(LdaImmutableContextSlot), R(0), U8(2), U8(0),
B(Star4),
/* 66 E> */ B(CallAnyReceiver), R(4), R(5), U8(1), U8(4),
B(Star2),
/* 66 E> */ B(CallAnyReceiver), R(2), R(3), U8(1), U8(6),
B(LdaUndefined),
/* 70 S> */ B(Return),
]