Move feedback slot allocation to post-pass
R=mvstanton@chromium.org, svenpanne@chromium.org Review URL: https://codereview.chromium.org/670953003 Cr-Commit-Position: refs/heads/master@{#25348}
This commit is contained in:
parent
45ff9d53c5
commit
1503d0e78c
@ -64,6 +64,21 @@ class AstNumberingVisitor FINAL : public AstVisitor {
|
||||
properties_.flags()->Add(kDontCache);
|
||||
}
|
||||
|
||||
template <typename Node>
|
||||
void ReserveFeedbackSlots(Node* node) {
|
||||
FeedbackVectorRequirements reqs = node->ComputeFeedbackRequirements();
|
||||
if (reqs.slots() > 0) {
|
||||
node->SetFirstFeedbackSlot(
|
||||
FeedbackVectorSlot(properties_.feedback_slots()));
|
||||
properties_.increase_feedback_slots(reqs.slots());
|
||||
}
|
||||
if (reqs.ic_slots() > 0) {
|
||||
node->SetFirstFeedbackICSlot(
|
||||
FeedbackVectorICSlot(properties_.ic_feedback_slots()));
|
||||
properties_.increase_ic_feedback_slots(reqs.ic_slots());
|
||||
}
|
||||
}
|
||||
|
||||
BailoutReason dont_optimize_reason() const {
|
||||
return (dont_turbofan_reason_ != kNoReason) ? dont_turbofan_reason_
|
||||
: dont_crankshaft_reason_;
|
||||
@ -145,6 +160,7 @@ void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) {
|
||||
if (node->var()->IsLookupSlot()) {
|
||||
DisableCrankshaft(kReferenceToAVariableWhichRequiresDynamicLookup);
|
||||
}
|
||||
ReserveFeedbackSlots(node);
|
||||
node->set_base_id(ReserveIdRange(VariableProxy::num_ids()));
|
||||
}
|
||||
|
||||
@ -158,6 +174,7 @@ void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
|
||||
void AstNumberingVisitor::VisitSuperReference(SuperReference* node) {
|
||||
IncrementNodeCount();
|
||||
DisableTurbofan(kSuperReference);
|
||||
ReserveFeedbackSlots(node);
|
||||
node->set_base_id(ReserveIdRange(SuperReference::num_ids()));
|
||||
Visit(node->this_var());
|
||||
}
|
||||
@ -215,6 +232,7 @@ void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
|
||||
void AstNumberingVisitor::VisitYield(Yield* node) {
|
||||
IncrementNodeCount();
|
||||
DisableCrankshaft(kYield);
|
||||
ReserveFeedbackSlots(node);
|
||||
node->set_base_id(ReserveIdRange(Yield::num_ids()));
|
||||
Visit(node->generator_object());
|
||||
Visit(node->expression());
|
||||
@ -319,6 +337,7 @@ void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) {
|
||||
|
||||
void AstNumberingVisitor::VisitProperty(Property* node) {
|
||||
IncrementNodeCount();
|
||||
ReserveFeedbackSlots(node);
|
||||
node->set_base_id(ReserveIdRange(Property::num_ids()));
|
||||
Visit(node->key());
|
||||
Visit(node->obj());
|
||||
@ -353,6 +372,7 @@ void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) {
|
||||
void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
|
||||
IncrementNodeCount();
|
||||
DisableSelfOptimization();
|
||||
ReserveFeedbackSlots(node);
|
||||
node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
|
||||
Visit(node->each());
|
||||
Visit(node->enumerable());
|
||||
@ -461,6 +481,7 @@ void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
|
||||
|
||||
void AstNumberingVisitor::VisitCall(Call* node) {
|
||||
IncrementNodeCount();
|
||||
ReserveFeedbackSlots(node);
|
||||
node->set_base_id(ReserveIdRange(Call::num_ids()));
|
||||
Visit(node->expression());
|
||||
VisitArguments(node->arguments());
|
||||
@ -469,6 +490,7 @@ void AstNumberingVisitor::VisitCall(Call* node) {
|
||||
|
||||
void AstNumberingVisitor::VisitCallNew(CallNew* node) {
|
||||
IncrementNodeCount();
|
||||
ReserveFeedbackSlots(node);
|
||||
node->set_base_id(ReserveIdRange(CallNew::num_ids()));
|
||||
Visit(node->expression());
|
||||
VisitArguments(node->arguments());
|
||||
@ -507,10 +529,6 @@ void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
|
||||
|
||||
|
||||
void AstNumberingVisitor::Renumber(FunctionLiteral* node) {
|
||||
properties_.flags()->Add(*node->flags());
|
||||
properties_.increase_feedback_slots(node->slot_count());
|
||||
properties_.increase_ic_feedback_slots(node->ic_slot_count());
|
||||
|
||||
if (node->scope()->HasIllegalRedeclaration()) {
|
||||
node->scope()->VisitIllegalRedeclaration(this);
|
||||
return;
|
||||
|
@ -1006,28 +1006,24 @@ CaseClause::CaseClause(Zone* zone, Expression* label,
|
||||
}
|
||||
#define REGULAR_NODE_WITH_FEEDBACK_SLOTS(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
add_slot_node(node); \
|
||||
}
|
||||
#define DONT_OPTIMIZE_NODE(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
}
|
||||
#define DONT_OPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
add_slot_node(node); \
|
||||
}
|
||||
#define DONT_TURBOFAN_NODE(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
}
|
||||
#define DONT_TURBOFAN_NODE_WITH_FEEDBACK_SLOTS(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
add_slot_node(node); \
|
||||
}
|
||||
#define DONT_SELFOPTIMIZE_NODE(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
}
|
||||
#define DONT_SELFOPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
add_slot_node(node); \
|
||||
}
|
||||
#define DONT_CACHE_NODE(NodeType) \
|
||||
void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
|
||||
@ -1101,7 +1097,6 @@ DONT_CACHE_NODE(ModuleLiteral)
|
||||
|
||||
|
||||
void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
|
||||
add_slot_node(node);
|
||||
}
|
||||
|
||||
#undef REGULAR_NODE
|
||||
|
33
src/ast.h
33
src/ast.h
@ -1705,6 +1705,7 @@ class VariableProxy FINAL : public Expression {
|
||||
}
|
||||
|
||||
FeedbackVectorICSlot VariableFeedbackSlot() {
|
||||
DCHECK(!FLAG_vector_ics || !variable_feedback_slot_.IsInvalid());
|
||||
return variable_feedback_slot_;
|
||||
}
|
||||
|
||||
@ -1790,6 +1791,7 @@ class Property FINAL : public Expression {
|
||||
}
|
||||
|
||||
FeedbackVectorICSlot PropertyFeedbackSlot() const {
|
||||
DCHECK(!FLAG_vector_ics || !property_feedback_slot_.IsInvalid());
|
||||
return property_feedback_slot_;
|
||||
}
|
||||
|
||||
@ -1834,7 +1836,10 @@ class Call FINAL : public Expression {
|
||||
}
|
||||
|
||||
bool HasCallFeedbackSlot() const { return !call_feedback_slot_.IsInvalid(); }
|
||||
FeedbackVectorICSlot CallFeedbackSlot() const { return call_feedback_slot_; }
|
||||
FeedbackVectorICSlot CallFeedbackSlot() const {
|
||||
DCHECK(!call_feedback_slot_.IsInvalid());
|
||||
return call_feedback_slot_;
|
||||
}
|
||||
|
||||
virtual SmallMapList* GetReceiverTypes() OVERRIDE {
|
||||
if (expression()->IsProperty()) {
|
||||
@ -1933,7 +1938,10 @@ class CallNew FINAL : public Expression {
|
||||
callnew_feedback_slot_ = slot;
|
||||
}
|
||||
|
||||
FeedbackVectorSlot CallNewFeedbackSlot() { return callnew_feedback_slot_; }
|
||||
FeedbackVectorSlot CallNewFeedbackSlot() {
|
||||
DCHECK(!callnew_feedback_slot_.IsInvalid());
|
||||
return callnew_feedback_slot_;
|
||||
}
|
||||
FeedbackVectorSlot AllocationSiteFeedbackSlot() {
|
||||
DCHECK(FLAG_pretenuring_call_new);
|
||||
return CallNewFeedbackSlot().next();
|
||||
@ -1997,6 +2005,8 @@ class CallRuntime FINAL : public Expression {
|
||||
}
|
||||
|
||||
FeedbackVectorICSlot CallRuntimeFeedbackSlot() {
|
||||
DCHECK(!(FLAG_vector_ics && is_jsruntime()) ||
|
||||
!callruntime_feedback_slot_.IsInvalid());
|
||||
return callruntime_feedback_slot_;
|
||||
}
|
||||
|
||||
@ -2383,6 +2393,7 @@ class Yield FINAL : public Expression {
|
||||
}
|
||||
|
||||
FeedbackVectorICSlot KeyedLoadFeedbackSlot() {
|
||||
DCHECK(!FLAG_vector_ics || !yield_first_feedback_slot_.IsInvalid());
|
||||
return yield_first_feedback_slot_;
|
||||
}
|
||||
|
||||
@ -3159,8 +3170,6 @@ class AstConstructionVisitor BASE_EMBEDDED {
|
||||
public:
|
||||
AstConstructionVisitor() {}
|
||||
|
||||
AstProperties* ast_properties() { return &properties_; }
|
||||
|
||||
private:
|
||||
template<class> friend class AstNodeFactory;
|
||||
|
||||
@ -3169,22 +3178,6 @@ class AstConstructionVisitor BASE_EMBEDDED {
|
||||
void Visit##type(type* node);
|
||||
AST_NODE_LIST(DEF_VISIT)
|
||||
#undef DEF_VISIT
|
||||
|
||||
void add_slot_node(AstNode* slot_node) {
|
||||
FeedbackVectorRequirements reqs = slot_node->ComputeFeedbackRequirements();
|
||||
if (reqs.slots() > 0) {
|
||||
slot_node->SetFirstFeedbackSlot(
|
||||
FeedbackVectorSlot(properties_.feedback_slots()));
|
||||
properties_.increase_feedback_slots(reqs.slots());
|
||||
}
|
||||
if (reqs.ic_slots() > 0) {
|
||||
slot_node->SetFirstFeedbackICSlot(
|
||||
FeedbackVectorICSlot(properties_.ic_feedback_slots()));
|
||||
properties_.increase_ic_feedback_slots(reqs.ic_slots());
|
||||
}
|
||||
}
|
||||
|
||||
AstProperties properties_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -291,9 +291,11 @@ bool CompilationInfo::ShouldSelfOptimize() {
|
||||
void CompilationInfo::PrepareForCompilation(Scope* scope) {
|
||||
DCHECK(scope_ == NULL);
|
||||
scope_ = scope;
|
||||
}
|
||||
|
||||
|
||||
void CompilationInfo::EnsureFeedbackVector() {
|
||||
if (feedback_vector_.is_null()) {
|
||||
// Allocate the feedback vector too.
|
||||
feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(
|
||||
function()->slot_count(), function()->ic_slot_count());
|
||||
}
|
||||
@ -1326,8 +1328,18 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(
|
||||
if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
|
||||
Handle<Code> code = isolate->builtins()->CompileLazy();
|
||||
info.SetCode(code);
|
||||
// There's no need in theory for a lazy-compiled function to have a type
|
||||
// feedback vector, but some parts of the system expect all
|
||||
// SharedFunctionInfo instances to have one. The size of the vector depends
|
||||
// on how many feedback-needing nodes are in the tree, and when lazily
|
||||
// parsing we might not know that, if this function was never parsed before.
|
||||
// In that case the vector will be replaced the next time MakeCode is
|
||||
// called.
|
||||
info.EnsureFeedbackVector();
|
||||
scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate));
|
||||
} else if (Renumber(&info) && FullCodeGenerator::MakeCode(&info)) {
|
||||
// MakeCode will ensure that the feedback vector is present and
|
||||
// appropriately sized.
|
||||
DCHECK(!info.code().is_null());
|
||||
scope_info = ScopeInfo::Create(info.scope(), info.zone());
|
||||
} else {
|
||||
|
@ -235,6 +235,7 @@ class CompilationInfo {
|
||||
DCHECK(script_scope_ == NULL);
|
||||
script_scope_ = script_scope;
|
||||
}
|
||||
void EnsureFeedbackVector();
|
||||
Handle<TypeFeedbackVector> feedback_vector() const {
|
||||
return feedback_vector_;
|
||||
}
|
||||
|
@ -306,6 +306,9 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
|
||||
|
||||
TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
|
||||
|
||||
// Ensure that the feedback vector is large enough.
|
||||
info->EnsureFeedbackVector();
|
||||
|
||||
Handle<Script> script = info->script();
|
||||
if (!script->IsUndefined() && !script->source()->IsUndefined()) {
|
||||
int len = String::cast(script->source())->length();
|
||||
|
@ -605,17 +605,17 @@ static int GetArrayLength(Handle<JSArray> array) {
|
||||
}
|
||||
|
||||
|
||||
void FunctionInfoWrapper::SetInitialProperties(
|
||||
Handle<String> name, int start_position, int end_position, int param_num,
|
||||
int literal_count, int slot_count, int ic_slot_count, int parent_index) {
|
||||
void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
|
||||
int start_position,
|
||||
int end_position, int param_num,
|
||||
int literal_count,
|
||||
int parent_index) {
|
||||
HandleScope scope(isolate());
|
||||
this->SetField(kFunctionNameOffset_, name);
|
||||
this->SetSmiValueField(kStartPositionOffset_, start_position);
|
||||
this->SetSmiValueField(kEndPositionOffset_, end_position);
|
||||
this->SetSmiValueField(kParamNumOffset_, param_num);
|
||||
this->SetSmiValueField(kLiteralNumOffset_, literal_count);
|
||||
this->SetSmiValueField(kSlotNumOffset_, slot_count);
|
||||
this->SetSmiValueField(kICSlotNumOffset_, ic_slot_count);
|
||||
this->SetSmiValueField(kParentIndexOffset_, parent_index);
|
||||
}
|
||||
|
||||
@ -646,26 +646,18 @@ Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
|
||||
}
|
||||
|
||||
|
||||
Handle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
|
||||
MaybeHandle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
|
||||
Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
|
||||
Handle<TypeFeedbackVector> result;
|
||||
if (element->IsJSValue()) {
|
||||
Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
|
||||
Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
Handle<SharedFunctionInfo>::cast(raw_result);
|
||||
result = Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
|
||||
CHECK_EQ(result->Slots(), GetSlotCount());
|
||||
CHECK_EQ(result->ICSlots(), GetICSlotCount());
|
||||
return Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
|
||||
} else {
|
||||
// Scripts may never have a SharedFunctionInfo created, so
|
||||
// create a type feedback vector here.
|
||||
int slot_count = GetSlotCount();
|
||||
int ic_slot_count = GetICSlotCount();
|
||||
result =
|
||||
isolate()->factory()->NewTypeFeedbackVector(slot_count, ic_slot_count);
|
||||
// Scripts may never have a SharedFunctionInfo created.
|
||||
return MaybeHandle<TypeFeedbackVector>();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -706,10 +698,10 @@ class FunctionInfoListener {
|
||||
void FunctionStarted(FunctionLiteral* fun) {
|
||||
HandleScope scope(isolate());
|
||||
FunctionInfoWrapper info = FunctionInfoWrapper::Create(isolate());
|
||||
info.SetInitialProperties(
|
||||
fun->name(), fun->start_position(), fun->end_position(),
|
||||
fun->parameter_count(), fun->materialized_literal_count(),
|
||||
fun->slot_count(), fun->ic_slot_count(), current_parent_index_);
|
||||
info.SetInitialProperties(fun->name(), fun->start_position(),
|
||||
fun->end_position(), fun->parameter_count(),
|
||||
fun->materialized_literal_count(),
|
||||
current_parent_index_);
|
||||
current_parent_index_ = len_;
|
||||
SetElementSloppy(result_, len_, info.GetJSArray());
|
||||
len_++;
|
||||
@ -1201,10 +1193,12 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
|
||||
}
|
||||
shared_info->DisableOptimization(kLiveEdit);
|
||||
// Update the type feedback vector
|
||||
Handle<TypeFeedbackVector> feedback_vector =
|
||||
// Update the type feedback vector, if needed.
|
||||
MaybeHandle<TypeFeedbackVector> feedback_vector =
|
||||
compile_info_wrapper.GetFeedbackVector();
|
||||
shared_info->set_feedback_vector(*feedback_vector);
|
||||
if (!feedback_vector.is_null()) {
|
||||
shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
|
||||
}
|
||||
}
|
||||
|
||||
if (shared_info->debug_info()->IsDebugInfo()) {
|
||||
|
@ -282,7 +282,6 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
|
||||
void SetInitialProperties(Handle<String> name, int start_position,
|
||||
int end_position, int param_num, int literal_count,
|
||||
int slot_count, int ic_slot_count,
|
||||
int parent_index);
|
||||
|
||||
void SetFunctionCode(Handle<Code> function_code,
|
||||
@ -304,7 +303,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
|
||||
Handle<Code> GetFunctionCode();
|
||||
|
||||
Handle<TypeFeedbackVector> GetFeedbackVector();
|
||||
MaybeHandle<TypeFeedbackVector> GetFeedbackVector();
|
||||
|
||||
Handle<Object> GetCodeScopeInfo();
|
||||
|
||||
@ -314,12 +313,6 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
|
||||
int GetEndPosition() { return this->GetSmiValueField(kEndPositionOffset_); }
|
||||
|
||||
int GetSlotCount() {
|
||||
return this->GetSmiValueField(kSlotNumOffset_);
|
||||
}
|
||||
|
||||
int GetICSlotCount() { return this->GetSmiValueField(kICSlotNumOffset_); }
|
||||
|
||||
private:
|
||||
static const int kFunctionNameOffset_ = 0;
|
||||
static const int kStartPositionOffset_ = 1;
|
||||
@ -331,9 +324,7 @@ class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
|
||||
static const int kParentIndexOffset_ = 7;
|
||||
static const int kSharedFunctionInfoOffset_ = 8;
|
||||
static const int kLiteralNumOffset_ = 9;
|
||||
static const int kSlotNumOffset_ = 10;
|
||||
static const int kICSlotNumOffset_ = 11;
|
||||
static const int kSize_ = 12;
|
||||
static const int kSize_ = 10;
|
||||
|
||||
friend class JSArrayBasedStruct<FunctionInfoWrapper>;
|
||||
};
|
||||
|
@ -277,7 +277,6 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
|
||||
int expected_property_count = -1;
|
||||
int handler_count = 0;
|
||||
int parameter_count = 0;
|
||||
AstProperties ast_properties;
|
||||
const AstRawString* name = ast_value_factory()->empty_string();
|
||||
|
||||
Scope* function_scope = NewScope(scope, FUNCTION_SCOPE);
|
||||
@ -308,8 +307,6 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
|
||||
materialized_literal_count = function_state.materialized_literal_count();
|
||||
expected_property_count = function_state.expected_property_count();
|
||||
handler_count = function_state.handler_count();
|
||||
|
||||
ast_properties = *factory()->visitor()->ast_properties();
|
||||
}
|
||||
|
||||
FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
|
||||
@ -320,8 +317,6 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
|
||||
FunctionLiteral::kNotParenthesized, FunctionKind::kDefaultConstructor,
|
||||
pos);
|
||||
|
||||
function_literal->set_ast_properties(&ast_properties);
|
||||
|
||||
return function_literal;
|
||||
}
|
||||
|
||||
@ -968,7 +963,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
|
||||
FunctionLiteral::kNoDuplicateParameters,
|
||||
FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
|
||||
FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
|
||||
result->set_ast_properties(factory()->visitor()->ast_properties());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3553,7 +3547,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
|
||||
? FunctionLiteral::kIsParenthesized
|
||||
: FunctionLiteral::kNotParenthesized;
|
||||
AstProperties ast_properties;
|
||||
// Parse function body.
|
||||
{
|
||||
AstNodeFactory<AstConstructionVisitor> function_factory(
|
||||
@ -3721,8 +3714,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
scope->end_position(),
|
||||
CHECK_OK);
|
||||
}
|
||||
ast_properties = *factory()->visitor()->ast_properties();
|
||||
|
||||
if (allow_harmony_scoping() && strict_mode() == STRICT) {
|
||||
CheckConflictingVarDeclarations(scope, CHECK_OK);
|
||||
}
|
||||
@ -3734,7 +3725,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
num_parameters, duplicate_parameters, function_type,
|
||||
FunctionLiteral::kIsFunction, parenthesized, kind, pos);
|
||||
function_literal->set_function_token_position(function_token_pos);
|
||||
function_literal->set_ast_properties(&ast_properties);
|
||||
|
||||
if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
|
||||
return function_literal;
|
||||
|
@ -815,7 +815,6 @@ class PreParserExpression {
|
||||
|
||||
int position() const { return RelocInfo::kNoPosition; }
|
||||
void set_function_token_position(int position) {}
|
||||
void set_ast_properties(int* ast_properties) {}
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
@ -1098,14 +1097,6 @@ class PreParserFactory {
|
||||
int start_position, int end_position) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
// Return the object itself as AstVisitor and implement the needed
|
||||
// dummy method right in this class.
|
||||
PreParserFactory* visitor() { return this; }
|
||||
int* ast_properties() {
|
||||
static int dummy = 42;
|
||||
return &dummy;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -2632,7 +2623,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
|
||||
bool* ok) {
|
||||
typename Traits::Type::ScopePtr scope = this->NewScope(scope_, ARROW_SCOPE);
|
||||
typename Traits::Type::StatementList body;
|
||||
typename Traits::Type::AstProperties ast_properties;
|
||||
int num_parameters = -1;
|
||||
int materialized_literal_count = -1;
|
||||
int expected_property_count = -1;
|
||||
@ -2714,8 +2704,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
|
||||
|
||||
if (allow_harmony_scoping() && strict_mode() == STRICT)
|
||||
this->CheckConflictingVarDeclarations(scope, CHECK_OK);
|
||||
|
||||
ast_properties = *factory()->visitor()->ast_properties();
|
||||
}
|
||||
|
||||
FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
|
||||
@ -2727,7 +2715,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
|
||||
start_pos);
|
||||
|
||||
function_literal->set_function_token_position(start_pos);
|
||||
function_literal->set_ast_properties(&ast_properties);
|
||||
|
||||
if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
|
||||
|
||||
|
@ -348,20 +348,19 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) {
|
||||
*v8::Handle<v8::Function>::Cast(
|
||||
CcTest::global()->Get(v8_str("morphing_call"))));
|
||||
|
||||
// Not compiled, and so no feedback vector allocated yet.
|
||||
CHECK(!f->shared()->is_compiled());
|
||||
CHECK_EQ(0, f->shared()->feedback_vector()->Slots());
|
||||
CHECK_EQ(0, f->shared()->feedback_vector()->ICSlots());
|
||||
|
||||
CompileRun("morphing_call();");
|
||||
|
||||
// Now a feedback vector is allocated.
|
||||
CHECK(f->shared()->is_compiled());
|
||||
int expected_slots = 0;
|
||||
int expected_ic_slots = FLAG_vector_ics ? 2 : 1;
|
||||
CHECK_EQ(expected_slots, f->shared()->feedback_vector()->Slots());
|
||||
CHECK_EQ(expected_ic_slots, f->shared()->feedback_vector()->ICSlots());
|
||||
|
||||
// And yet it's not compiled.
|
||||
CHECK(!f->shared()->is_compiled());
|
||||
|
||||
CompileRun("morphing_call();");
|
||||
|
||||
// The vector should have the same size despite the new scoping.
|
||||
CHECK_EQ(expected_slots, f->shared()->feedback_vector()->Slots());
|
||||
CHECK_EQ(expected_ic_slots, f->shared()->feedback_vector()->ICSlots());
|
||||
CHECK(f->shared()->is_compiled());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user