Move final parts of class literal setup into a single runtime call
This avoids multiple ToFastProperties runtime calls and additional stack pushes in strong mode. BUG= Review URL: https://codereview.chromium.org/1266573003 Cr-Commit-Position: refs/heads/master@{#29925}
This commit is contained in:
parent
f469b21143
commit
c1970988c0
@ -1639,24 +1639,15 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
|
||||
}
|
||||
}
|
||||
|
||||
// Transform both the class literal and the prototype to fast properties.
|
||||
const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1);
|
||||
NewNode(op, environment()->Pop()); // prototype
|
||||
NewNode(op, environment()->Pop()); // literal
|
||||
if (is_strong(language_mode())) {
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
proto =
|
||||
NewNode(javascript()->CallRuntime(Runtime::kObjectFreeze, 1), proto);
|
||||
// Freezing the prototype should never deopt.
|
||||
PrepareFrameState(proto, BailoutId::None());
|
||||
// Freeze the constructor.
|
||||
literal =
|
||||
NewNode(javascript()->CallRuntime(Runtime::kObjectFreeze, 1), literal);
|
||||
// Freezing the constructor should never deopt.
|
||||
PrepareFrameState(literal, BailoutId::None());
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
environment()->Pop(); // proto
|
||||
environment()->Pop(); // literal
|
||||
const Operator* op = javascript()->CallRuntime(
|
||||
is_strong(language_mode()) ? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
literal = NewNode(op, literal, proto);
|
||||
|
||||
// Assign to class variable.
|
||||
if (expr->scope() != NULL) {
|
||||
|
@ -192,6 +192,8 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
|
||||
switch (function) {
|
||||
case Runtime::kAllocateInTargetSpace:
|
||||
case Runtime::kDateField:
|
||||
case Runtime::kFinalizeClassDefinition: // TODO(conradw): Is it safe?
|
||||
case Runtime::kFinalizeClassDefinitionStrong: // TODO(conradw): Is it safe?
|
||||
case Runtime::kDefineClassMethod: // TODO(jarin): Is it safe?
|
||||
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
|
||||
case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe?
|
||||
|
@ -2567,24 +2567,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ ldr(scratch,
|
||||
FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ push(r0);
|
||||
__ push(scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2263,24 +2263,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ Ldr(scratch,
|
||||
FieldMemOperand(x0, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ push(x0);
|
||||
__ Push(scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2479,24 +2479,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ mov(scratch,
|
||||
FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ push(eax);
|
||||
__ Push(scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2558,23 +2558,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ lw(scratch,
|
||||
FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ Push(v0, scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2555,23 +2555,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ ld(scratch,
|
||||
FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ Push(v0, scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2572,23 +2572,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ LoadP(scratch,
|
||||
FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ Push(r3, scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2474,24 +2474,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ movp(scratch,
|
||||
FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ Push(rax);
|
||||
__ Push(scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2470,24 +2470,12 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
|
||||
}
|
||||
}
|
||||
|
||||
// prototype
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
// constructor
|
||||
__ CallRuntime(Runtime::kToFastProperties, 1);
|
||||
|
||||
if (is_strong(language_mode())) {
|
||||
__ mov(scratch,
|
||||
FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset));
|
||||
__ push(eax);
|
||||
__ push(scratch);
|
||||
// TODO(conradw): It would be more efficient to define the properties with
|
||||
// the right attributes the first time round.
|
||||
// Freeze the prototype.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
// Freeze the constructor.
|
||||
__ CallRuntime(Runtime::kObjectFreeze, 1);
|
||||
}
|
||||
// Set both the prototype and constructor to have fast properties, and also
|
||||
// freeze them in strong mode.
|
||||
__ CallRuntime(is_strong(language_mode())
|
||||
? Runtime::kFinalizeClassDefinitionStrong
|
||||
: Runtime::kFinalizeClassDefinition,
|
||||
2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -253,6 +253,36 @@ RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_FinalizeClassDefinition) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 2);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, constructor, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, prototype, 1);
|
||||
|
||||
JSObject::MigrateSlowToFast(prototype, 0, "RuntimeToFastProperties");
|
||||
JSObject::MigrateSlowToFast(constructor, 0, "RuntimeToFastProperties");
|
||||
|
||||
return *constructor;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_FinalizeClassDefinitionStrong) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 2);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, constructor, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, prototype, 1);
|
||||
|
||||
JSObject::MigrateSlowToFast(prototype, 0, "RuntimeToFastProperties");
|
||||
JSObject::MigrateSlowToFast(constructor, 0, "RuntimeToFastProperties");
|
||||
|
||||
RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::Freeze(prototype));
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
|
||||
JSObject::Freeze(constructor));
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
|
||||
HandleScope shs(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
|
@ -84,6 +84,8 @@ namespace internal {
|
||||
F(HomeObjectSymbol, 0, 1) \
|
||||
F(DefineClass, 6, 1) \
|
||||
F(DefineClassStrong, 6, 1) \
|
||||
F(FinalizeClassDefinition, 2, 1) \
|
||||
F(FinalizeClassDefinitionStrong, 2, 1) \
|
||||
F(DefineClassMethod, 3, 1) \
|
||||
F(ClassGetSourceCode, 1, 1) \
|
||||
F(LoadFromSuper, 4, 1) \
|
||||
|
Loading…
Reference in New Issue
Block a user