Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Unified Diff: src/ast/ast.cc

Issue 2625873009: [ast] Remove heap accesses from AST numbering (Closed)
Patch Set: Address nits Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ast/ast.h ('k') | src/ast/ast-numbering.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ast/ast.cc
diff --git a/src/ast/ast.cc b/src/ast/ast.cc
index f31b5d142ebc28772d6c4d03ec1f145d0f717194..c63f90ecf11f398ebfdecf5c6fd25356dd934f83 100644
--- a/src/ast/ast.cc
+++ b/src/ast/ast.cc
@@ -73,6 +73,10 @@ bool Expression::IsSmiLiteral() const {
return IsLiteral() && AsLiteral()->raw_value()->IsSmi();
}
+bool Expression::IsNumberLiteral() const {
+ return IsLiteral() && AsLiteral()->raw_value()->IsNumber();
+}
+
bool Expression::IsStringLiteral() const {
return IsLiteral() && AsLiteral()->raw_value()->IsString();
}
@@ -200,9 +204,7 @@ void VariableProxy::BindTo(Variable* var) {
var->set_is_used();
}
-
-void VariableProxy::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void VariableProxy::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
if (UsesVariableFeedbackSlot()) {
// VariableProxies that point to the same Variable within a function can
@@ -238,8 +240,7 @@ static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec,
}
}
-void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void ForInStatement::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
AssignVectorSlots(each(), spec, &each_slot_);
for_in_feedback_slot_ = spec->AddGeneralSlot();
@@ -256,15 +257,12 @@ Assignment::Assignment(Token::Value op, Expression* target, Expression* value,
StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op);
}
-void Assignment::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void Assignment::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
AssignVectorSlots(target(), spec, &slot_);
}
-
-void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void CountOperation::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
AssignVectorSlots(expression(), spec, &slot_);
// Assign a slot to collect feedback about binary operations. Used only in
@@ -373,8 +371,7 @@ ClassLiteralProperty::ClassLiteralProperty(Expression* key, Expression* value,
kind_(kind),
is_static_(is_static) {}
-void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void ClassLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
// This logic that computes the number of slots needed for vector store
// ICs must mirror BytecodeGenerator::VisitClassLiteral.
@@ -410,8 +407,7 @@ void ObjectLiteral::Property::set_emit_store(bool emit_store) {
bool ObjectLiteral::Property::emit_store() const { return emit_store_; }
-void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void ObjectLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
// This logic that computes the number of slots needed for vector store
// ics must mirror FullCodeGenerator::VisitObjectLiteral.
@@ -432,7 +428,7 @@ void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
case ObjectLiteral::Property::COMPUTED:
// It is safe to use [[Put]] here because the boilerplate already
// contains computed properties with an uninitialized value.
- if (key->value()->IsInternalizedString()) {
+ if (key->IsStringLiteral()) {
if (property->emit_store()) {
property->SetSlot(spec->AddStoreICSlot());
if (FunctionLiteral::NeedsHomeObject(value)) {
@@ -512,13 +508,8 @@ bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) {
property->kind() != ObjectLiteral::Property::PROTOTYPE;
}
-
-void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
- if (!constant_properties_.is_null()) return;
-
- // Allocate a fixed array to hold all the constant properties.
- Handle<FixedArray> constant_properties = isolate->factory()->NewFixedArray(
- boilerplate_properties_ * 2, TENURED);
+void ObjectLiteral::InitDepthAndFlags() {
+ if (depth_ > 0) return;
int position = 0;
// Accumulate the value in local variables and store it at the end.
@@ -542,50 +533,43 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
if (m_literal != NULL) {
- m_literal->BuildConstants(isolate);
+ m_literal->InitDepthAndFlags();
if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1;
}
- // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
- // value for COMPUTED properties, the real value is filled in at
- // runtime. The enumeration order is maintained.
- Handle<Object> key = property->key()->AsLiteral()->value();
- Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
+ const AstValue* key = property->key()->AsLiteral()->raw_value();
+ Expression* value = property->value();
+
+ bool is_compile_time_value = CompileTimeValue::IsCompileTimeValue(value);
// Ensure objects that may, at any point in time, contain fields with double
// representation are always treated as nested objects. This is true for
- // computed fields (value is undefined), and smi and double literals
- // (value->IsNumber()).
+ // computed fields, and smi and double literals.
// TODO(verwaest): Remove once we can store them inline.
if (FLAG_track_double_fields &&
- (value->IsNumber() || value->IsUninitialized(isolate))) {
+ (value->IsNumberLiteral() || !is_compile_time_value)) {
bit_field_ = MayStoreDoublesField::update(bit_field_, true);
}
- is_simple = is_simple && !value->IsUninitialized(isolate);
+ is_simple = is_simple && is_compile_time_value;
// Keep track of the number of elements in the object literal and
// the largest element index. If the largest element index is
// much larger than the number of elements, creating an object
// literal with fast elements will be a waste of space.
uint32_t element_index = 0;
- if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) {
+ if (key->IsString() && key->AsString()->AsArrayIndex(&element_index)) {
max_element_index = Max(element_index, max_element_index);
elements++;
- key = isolate->factory()->NewNumberFromUint(element_index);
- } else if (key->ToArrayIndex(&element_index)) {
+ } else if (key->ToUint32(&element_index) && element_index != kMaxUInt32) {
max_element_index = Max(element_index, max_element_index);
elements++;
- } else if (key->IsNumber()) {
- key = isolate->factory()->NumberToString(key);
}
- // Add name, value pair to the fixed array.
- constant_properties->set(position++, *key);
- constant_properties->set(position++, *value);
+ // Increment the position for the key and the value.
+ position += 2;
}
- constant_properties_ = constant_properties;
bit_field_ = FastElementsField::update(
bit_field_,
(max_element_index <= 32) || ((2 * elements) >= max_element_index));
@@ -595,6 +579,52 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
set_depth(depth_acc);
}
+void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
+ if (!constant_properties_.is_null()) return;
+
+ // Allocate a fixed array to hold all the constant properties.
+ Handle<FixedArray> constant_properties =
+ isolate->factory()->NewFixedArray(boilerplate_properties_ * 2, TENURED);
+
+ int position = 0;
+ for (int i = 0; i < properties()->length(); i++) {
+ ObjectLiteral::Property* property = properties()->at(i);
+ if (!IsBoilerplateProperty(property)) {
+ continue;
+ }
+
+ if (static_cast<uint32_t>(position) == boilerplate_properties_ * 2) {
+ DCHECK(property->is_computed_name());
+ break;
+ }
+ DCHECK(!property->is_computed_name());
+
+ MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
+ if (m_literal != NULL) {
+ m_literal->BuildConstants(isolate);
+ }
+
+ // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
+ // value for COMPUTED properties, the real value is filled in at
+ // runtime. The enumeration order is maintained.
+ Handle<Object> key = property->key()->AsLiteral()->value();
+ Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
+
+ uint32_t element_index = 0;
+ if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) {
+ key = isolate->factory()->NewNumberFromUint(element_index);
+ } else if (key->IsNumber() && !key->ToArrayIndex(&element_index)) {
+ key = isolate->factory()->NumberToString(key);
+ }
+
+ // Add name, value pair to the fixed array.
+ constant_properties->set(position++, *key);
+ constant_properties->set(position++, *value);
+ }
+
+ constant_properties_ = constant_properties;
+}
+
bool ObjectLiteral::IsFastCloningSupported() const {
// The FastCloneShallowObject builtin doesn't copy elements, and object
// literals don't support copy-on-write (COW) elements for now.
@@ -604,6 +634,37 @@ bool ObjectLiteral::IsFastCloningSupported() const {
kMaximumClonedShallowObjectProperties;
}
+void ArrayLiteral::InitDepthAndFlags() {
+ DCHECK_LT(first_spread_index_, 0);
+
+ if (depth_ > 0) return;
+
+ int constants_length = values()->length();
+
+ // Fill in the literals.
+ bool is_simple = true;
+ int depth_acc = 1;
+ int array_index = 0;
+ for (; array_index < constants_length; array_index++) {
+ Expression* element = values()->at(array_index);
+ DCHECK(!element->IsSpread());
+ MaterializedLiteral* m_literal = element->AsMaterializedLiteral();
+ if (m_literal != NULL) {
+ m_literal->InitDepthAndFlags();
+ if (m_literal->depth() + 1 > depth_acc) {
+ depth_acc = m_literal->depth() + 1;
+ }
+ }
+
+ if (!CompileTimeValue::IsCompileTimeValue(element)) {
+ is_simple = false;
+ }
+ }
+
+ set_is_simple(is_simple);
+ set_depth(depth_acc);
+}
+
void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
DCHECK_LT(first_spread_index_, 0);
@@ -615,8 +676,6 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
isolate->factory()->NewFixedArrayWithHoles(constants_length);
// Fill in the literals.
- bool is_simple = true;
- int depth_acc = 1;
bool is_holey = false;
int array_index = 0;
for (; array_index < constants_length; array_index++) {
@@ -625,9 +684,6 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
MaterializedLiteral* m_literal = element->AsMaterializedLiteral();
if (m_literal != NULL) {
m_literal->BuildConstants(isolate);
- if (m_literal->depth() + 1 > depth_acc) {
- depth_acc = m_literal->depth() + 1;
- }
}
// New handle scope here, needs to be after BuildContants().
@@ -640,7 +696,6 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
if (boilerplate_value->IsUninitialized(isolate)) {
boilerplate_value = handle(Smi::kZero, isolate);
- is_simple = false;
}
kind = GetMoreGeneralElementsKind(kind,
@@ -652,7 +707,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
// Simple and shallow arrays can be lazily copied, we transform the
// elements array to a copy-on-write array.
- if (is_simple && depth_acc == 1 && array_index > 0 &&
+ if (is_simple() && depth() == 1 && array_index > 0 &&
IsFastSmiOrObjectElementsKind(kind)) {
fixed_array->set_map(isolate->heap()->fixed_cow_array_map());
}
@@ -671,8 +726,6 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
isolate->factory()->NewConstantElementsPair(kind, elements);
constant_elements_ = literals;
- set_is_simple(is_simple);
- set_depth(depth_acc);
}
bool ArrayLiteral::IsFastCloningSupported() const {
@@ -681,8 +734,7 @@ bool ArrayLiteral::IsFastCloningSupported() const {
ConstructorBuiltinsAssembler::kMaximumClonedShallowArrayElements;
}
-void ArrayLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void ArrayLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
// This logic that computes the number of slots needed for vector store
// ics must mirror FullCodeGenerator::VisitArrayLiteral.
@@ -710,6 +762,16 @@ Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression,
return isolate->factory()->uninitialized_value();
}
+void MaterializedLiteral::InitDepthAndFlags() {
+ if (IsArrayLiteral()) {
+ return AsArrayLiteral()->InitDepthAndFlags();
+ }
+ if (IsObjectLiteral()) {
+ return AsObjectLiteral()->InitDepthAndFlags();
+ }
+ DCHECK(IsRegExpLiteral());
+ DCHECK_LE(1, depth()); // Depth should be initialized.
+}
void MaterializedLiteral::BuildConstants(Isolate* isolate) {
if (IsArrayLiteral()) {
@@ -719,7 +781,6 @@ void MaterializedLiteral::BuildConstants(Isolate* isolate) {
return AsObjectLiteral()->BuildConstantProperties(isolate);
}
DCHECK(IsRegExpLiteral());
- DCHECK(depth() >= 1); // Depth should be initialized.
}
@@ -743,8 +804,7 @@ void BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
}
void BinaryOperation::AssignFeedbackVectorSlots(
- Isolate* isolate, FeedbackVectorSpec* spec,
- FeedbackVectorSlotCache* cache) {
+ FeedbackVectorSpec* spec, FeedbackVectorSlotCache* cache) {
// Feedback vector slot is only used by interpreter for binary operations.
// Full-codegen uses AstId to record type feedback.
switch (op()) {
@@ -765,8 +825,7 @@ static bool IsTypeof(Expression* expr) {
}
void CompareOperation::AssignFeedbackVectorSlots(
- Isolate* isolate, FeedbackVectorSpec* spec,
- FeedbackVectorSlotCache* cache_) {
+ FeedbackVectorSpec* spec, FeedbackVectorSlotCache* cache_) {
// Feedback vector slot is only used by interpreter for binary operations.
// Full-codegen uses AstId to record type feedback.
switch (op()) {
@@ -924,7 +983,7 @@ bool Expression::IsMonomorphic() const {
}
}
-void Call::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+void Call::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
ic_slot_ = spec->AddCallICSlot();
}
@@ -963,8 +1022,7 @@ CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements,
statements_(statements),
compare_type_(AstType::None()) {}
-void CaseClause::AssignFeedbackVectorSlots(Isolate* isolate,
- FeedbackVectorSpec* spec,
+void CaseClause::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
type_feedback_slot_ = spec->AddInterpreterCompareICSlot();
}
« no previous file with comments | « src/ast/ast.h ('k') | src/ast/ast-numbering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698