Commit 331a2938 authored by Gus Caplan's avatar Gus Caplan Committed by Commit Bot

[Torque] Add flags to NewExpression

This allows `new (Pretenured) X{}` to force a pretenured allocation.

Bug: v8:7793
Change-Id: Ib09f186b3b503b9b23291c39c1390f120d25eebe
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2288409
Commit-Queue: Gus Caplan <me@gus.host>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68801}
parent bc52bf69
......@@ -234,7 +234,8 @@ extern enum ElementsKind extends int32 {
...
}
extern enum AllocationFlag constexpr 'CodeStubAssembler::AllocationFlag' {
extern enum AllocationFlag extends int32
constexpr 'CodeStubAssembler::AllocationFlag' {
kNone,
kDoubleAlignment,
kPretenured,
......@@ -840,6 +841,8 @@ extern operator '&' macro Word32And(bool, bool): bool;
extern operator '|' macro Word32Or(bool, bool): bool;
extern operator '==' macro Word32Equal(bool, bool): bool;
extern operator '!=' macro Word32NotEqual(bool, bool): bool;
extern operator '|' macro ConstexprWord32Or(
constexpr int32, constexpr int32): constexpr int32;
extern operator '+' macro Float64Add(float64, float64): float64;
extern operator '-' macro Float64Sub(float64, float64): float64;
......
......@@ -147,12 +147,23 @@ macro ValidAllocationSize(sizeInBytes: intptr, map: Map): bool {
type UninitializedHeapObject extends HeapObject;
extern macro AllocateAllowLOS(intptr): UninitializedHeapObject;
extern macro GetInstanceTypeMap(constexpr InstanceType): Map;
extern macro Allocate(
intptr, constexpr AllocationFlag): UninitializedHeapObject;
macro Allocate(sizeInBytes: intptr, map: Map): UninitializedHeapObject {
const kAllocateBaseFlags: constexpr AllocationFlag =
AllocationFlag::kAllowLargeObjectAllocation;
macro AllocateFromNew(
sizeInBytes: intptr, map: Map, pretenured: bool): UninitializedHeapObject {
assert(ValidAllocationSize(sizeInBytes, map));
return AllocateAllowLOS(sizeInBytes);
if (pretenured) {
return Allocate(
sizeInBytes,
%RawConstexprCast<constexpr AllocationFlag>(
kAllocateBaseFlags | AllocationFlag::kPretenured));
} else {
return Allocate(sizeInBytes, kAllocateBaseFlags);
}
}
macro InitializeFieldsFromIterator<T: type, Iterator: type>(
......
......@@ -807,9 +807,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<HeapObject> AllocateInNewSpace(int size, AllocationFlags flags = kNone);
TNode<HeapObject> Allocate(TNode<IntPtrT> size,
AllocationFlags flags = kNone);
TNode<HeapObject> AllocateAllowLOS(TNode<IntPtrT> size) {
return Allocate(size, AllocationFlag::kAllowLargeObjectAllocation);
}
TNode<HeapObject> Allocate(int size, AllocationFlags flags = kNone);
TNode<HeapObject> InnerAllocate(TNode<HeapObject> previous, int offset);
......@@ -3634,6 +3631,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return val;
}
int32_t ConstexprWord32Or(int32_t a, int32_t b) { return a | b; }
bool ConstexprUintPtrLessThan(uintptr_t a, uintptr_t b) { return a < b; }
// CSA does not support 64-bit types on 32-bit platforms so as a workaround
......
......@@ -580,10 +580,11 @@ struct AssumeTypeImpossibleExpression : Expression {
struct NewExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(NewExpression)
NewExpression(SourcePosition pos, TypeExpression* type,
std::vector<NameAndExpression> initializers)
std::vector<NameAndExpression> initializers, bool pretenured)
: Expression(kKind, pos),
type(type),
initializers(std::move(initializers)) {}
initializers(std::move(initializers)),
pretenured(pretenured) {}
void VisitAllSubExpressions(VisitCallback callback) override {
for (auto& initializer : initializers) {
......@@ -594,6 +595,7 @@ struct NewExpression : Expression {
TypeExpression* type;
std::vector<NameAndExpression> initializers;
bool pretenured;
};
enum class ImplicitKind { kNoImplicit, kJSImplicit, kImplicit };
......
......@@ -1516,8 +1516,10 @@ VisitResult ImplementationVisitor::Visit(NewExpression* expr) {
Arguments allocate_arguments;
allocate_arguments.parameters.push_back(layout.size);
allocate_arguments.parameters.push_back(object_map);
allocate_arguments.parameters.push_back(
GenerateBoolConstant(expr->pretenured));
VisitResult allocate_result = GenerateCall(
QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, "Allocate"),
QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, "AllocateFromNew"),
allocate_arguments, {class_type}, false);
DCHECK(allocate_result.IsOnStack());
......
......@@ -381,9 +381,13 @@ base::Optional<ParseResult> MakeMethodCall(ParseResultIterator* child_results) {
base::Optional<ParseResult> MakeNewExpression(
ParseResultIterator* child_results) {
bool pretenured = child_results->NextAs<bool>();
auto type = child_results->NextAs<TypeExpression*>();
auto initializers = child_results->NextAs<std::vector<NameAndExpression>>();
Expression* result = MakeNode<NewExpression>(type, std::move(initializers));
Expression* result =
MakeNode<NewExpression>(type, std::move(initializers), pretenured);
return ParseResult{result};
}
......@@ -2229,6 +2233,13 @@ struct TorqueGrammar : Grammar {
&argumentList},
MakeIntrinsicCallExpression)};
// Result: Expression*
Symbol newExpression = {
Rule({Token("new"),
CheckIf(Sequence({Token("("), Token("Pretenured"), Token(")")})),
&simpleType, &initializerList},
MakeNewExpression)};
// Result: Expression*
Symbol primaryExpression = {
Rule({&callExpression}),
......@@ -2243,7 +2254,7 @@ struct TorqueGrammar : Grammar {
Rule({&decimalLiteral}, MakeNumberLiteralExpression),
Rule({&stringLiteral}, MakeStringLiteralExpression),
Rule({&simpleType, &initializerList}, MakeStructExpression),
Rule({Token("new"), &simpleType, &initializerList}, MakeNewExpression),
Rule({&newExpression}),
Rule({Token("("), expression, Token(")")})};
// Result: Expression*
......
......@@ -836,6 +836,22 @@ TEST(TestGeneratedCastOperators) {
ft.Call();
}
TEST(TestNewPretenured) {
CcTest::InitializeVM();
Isolate* isolate(CcTest::i_isolate());
i::HandleScope scope(isolate);
CodeAssemblerTester asm_tester(isolate, 1);
TestTorqueAssembler m(asm_tester.state());
{
Handle<Context> context =
Utils::OpenHandle(*v8::Isolate::GetCurrent()->GetCurrentContext());
m.TestNewPretenured(m.UncheckedCast<Context>(m.HeapConstant(context)));
m.Return(m.UndefinedConstant());
}
FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -1304,4 +1304,14 @@ macro TestGeneratedCastOperators(implicit context: Context)() {
elements, Convert<Smi>(0), jsf);
assert(Is<JSArgumentsObject>(fastArgs));
}
extern runtime InYoungGeneration(implicit context: Context)(HeapObject):
Boolean;
@export
macro TestNewPretenured(implicit context: Context)() {
const obj = new (Pretenured) ExportedSubClassBase{a: Undefined, b: Null};
assert(Is<ExportedSubClassBase>(obj));
assert(InYoungGeneration(obj) == False);
}
}
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