20 handle(info->closure()->shared()->code()),
22 handle(info->closure()->context()->native_context()),
24 store_(info->zone()) {
25 InitializeAstVisitor(info->
zone());
29 #define RECURSE(call) \
31 DCHECK(!visitor->HasStackOverflow()); \
33 if (visitor->HasStackOverflow()) return; \
55 os <<
" observed " << (var->
IsParameter() ?
"param" :
"local") <<
" ";
56 var->
name()->Print(os);
57 os <<
" : " <<
Brief(value) <<
" -> ";
74 JavaScriptFrameIterator it(isolate());
87 for (
int i = 0;
i < params;
i++) {
91 for (
int i = 0;
i < locals;
i++) {
96 if (FLAG_trace_osr && FLAG_print_scopes) {
101 for (
int i = 0;
i < params;
i++) {
110 for (
int i = 0;
i < locals;
i++) {
111 PrintObserved(local_vars.
at(
i),
120 #define RECURSE(call) \
122 DCHECK(!HasStackOverflow()); \
124 if (HasStackOverflow()) return; \
129 for (
int i = 0;
i < stmts->length(); ++
i) {
132 if (stmt->
IsJump())
break;
137 void AstTyper::VisitBlock(Block* stmt) {
139 if (stmt->labels() !=
NULL) {
145 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
146 RECURSE(Visit(stmt->expression()));
150 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) {
154 void AstTyper::VisitIfStatement(IfStatement* stmt) {
156 if (!stmt->condition()->ToBooleanIsTrue() &&
157 !stmt->condition()->ToBooleanIsFalse()) {
158 stmt->condition()->RecordToBooleanTypeFeedback(
oracle());
161 RECURSE(Visit(stmt->condition()));
163 RECURSE(Visit(stmt->then_statement()));
166 RECURSE(Visit(stmt->else_statement()));
168 then_effects.Alt(else_effects);
173 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
178 void AstTyper::VisitBreakStatement(BreakStatement* stmt) {
183 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
186 stmt->expression()->RecordToBooleanTypeFeedback(
oracle());
188 RECURSE(Visit(stmt->expression()));
193 void AstTyper::VisitWithStatement(WithStatement* stmt) {
199 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
202 ZoneList<CaseClause*>* clauses = stmt->cases();
204 bool complex_effects =
false;
206 for (
int i = 0;
i < clauses->length(); ++
i) {
207 CaseClause* clause = clauses->at(
i);
211 if (!clause->is_default()) {
212 Expression* label = clause->label();
218 &tag_type, &label_type, &combined_type);
221 clause->set_compare_type(combined_type);
224 if (!clause_effects.IsEmpty()) complex_effects =
true;
227 ZoneList<Statement*>* stmts = clause->statements();
230 if (stmts->is_empty() || stmts->last()->IsJump()) {
231 local_effects.Alt(clause_effects);
233 complex_effects =
true;
237 if (complex_effects) {
245 void AstTyper::VisitCaseClause(CaseClause* clause) {
250 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
252 if (!stmt->cond()->ToBooleanIsTrue()) {
253 stmt->cond()->RecordToBooleanTypeFeedback(
oracle());
267 void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
269 if (!stmt->cond()->ToBooleanIsTrue()) {
270 stmt->cond()->RecordToBooleanTypeFeedback(
oracle());
281 void AstTyper::VisitForStatement(ForStatement* stmt) {
282 if (stmt->init() !=
NULL) {
286 if (stmt->cond() !=
NULL) {
288 stmt->cond()->RecordToBooleanTypeFeedback(
oracle());
294 if (stmt->next() !=
NULL) {
302 void AstTyper::VisitForInStatement(ForInStatement* stmt) {
304 stmt->set_for_in_type(
static_cast<ForInStatement::ForInType
>(
305 oracle()->ForInType(stmt->ForInFeedbackSlot())));
307 RECURSE(Visit(stmt->enumerable()));
315 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {
316 RECURSE(Visit(stmt->iterable()));
323 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
325 RECURSE(Visit(stmt->try_block()));
329 RECURSE(Visit(stmt->catch_block()));
331 try_effects.Alt(catch_effects);
338 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
339 RECURSE(Visit(stmt->try_block()));
341 RECURSE(Visit(stmt->finally_block()));
345 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
350 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
351 expr->InitializeSharedInfo(Handle<Code>(
info_->
closure()->shared()->code()));
355 void AstTyper::VisitClassLiteral(ClassLiteral* expr) {}
358 void AstTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
362 void AstTyper::VisitConditional(Conditional* expr) {
364 expr->condition()->RecordToBooleanTypeFeedback(
oracle());
366 RECURSE(Visit(expr->condition()));
368 RECURSE(Visit(expr->then_expression()));
371 RECURSE(Visit(expr->else_expression()));
373 then_effects.Alt(else_effects);
377 expr->then_expression()->bounds(),
378 expr->else_expression()->bounds(), zone()));
382 void AstTyper::VisitVariableProxy(VariableProxy* expr) {
383 Variable* var = expr->var();
384 if (var->IsStackAllocated()) {
390 void AstTyper::VisitLiteral(Literal* expr) {
396 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
401 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
402 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
403 for (
int i = 0;
i < properties->length(); ++
i) {
404 ObjectLiteral::Property* prop = properties->at(
i);
407 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
409 prop->kind() == ObjectLiteral::Property::COMPUTED) {
410 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) {
411 prop->RecordTypeFeedback(
oracle());
422 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
423 ZoneList<Expression*>* values = expr->values();
424 for (
int i = 0;
i < values->length(); ++
i) {
425 Expression* value = values->at(
i);
433 void AstTyper::VisitAssignment(Assignment* expr) {
435 Property* prop = expr->target()->AsProperty();
437 TypeFeedbackId
id = expr->AssignmentFeedbackId();
438 expr->set_is_uninitialized(
oracle()->StoreIsUninitialized(
id));
439 if (!expr->IsUninitialized()) {
440 if (prop->key()->IsPropertyName()) {
441 Literal* lit_key = prop->key()->AsLiteral();
442 DCHECK(lit_key !=
NULL && lit_key->value()->IsString());
448 id, expr->GetReceiverTypes(), &store_mode);
449 expr->set_store_mode(store_mode);
455 expr->is_compound() ? expr->binary_operation() : expr->value();
456 RECURSE(Visit(expr->target()));
460 VariableProxy* proxy = expr->target()->AsVariableProxy();
461 if (proxy !=
NULL && proxy->var()->IsStackAllocated()) {
467 void AstTyper::VisitYield(Yield* expr) {
468 RECURSE(Visit(expr->generator_object()));
469 RECURSE(Visit(expr->expression()));
475 void AstTyper::VisitThrow(
Throw* expr) {
476 RECURSE(Visit(expr->exception()));
483 void AstTyper::VisitProperty(Property* expr) {
485 TypeFeedbackId
id = expr->PropertyFeedbackId();
486 expr->set_is_uninitialized(
oracle()->LoadIsUninitialized(
id));
487 if (!expr->IsUninitialized()) {
488 if (expr->key()->IsPropertyName()) {
489 Literal* lit_key = expr->key()->AsLiteral();
490 DCHECK(lit_key !=
NULL && lit_key->value()->IsString());
496 id, expr->GetReceiverTypes(), &is_string);
497 expr->set_is_string_access(is_string);
508 void AstTyper::VisitCall(Call* expr) {
510 RECURSE(Visit(expr->expression()));
511 if (!expr->expression()->IsProperty() &&
512 expr->IsUsingCallFeedbackSlot(isolate()) &&
513 oracle()->CallIsMonomorphic(expr->CallFeedbackSlot())) {
514 expr->set_target(
oracle()->GetCallTarget(expr->CallFeedbackSlot()));
515 Handle<AllocationSite> site =
517 expr->set_allocation_site(site);
520 ZoneList<Expression*>* args = expr->arguments();
521 for (
int i = 0;
i < args->length(); ++
i) {
522 Expression* arg = args->at(
i);
526 VariableProxy* proxy = expr->expression()->AsVariableProxy();
527 if (proxy !=
NULL && proxy->var()->is_possibly_eval(isolate())) {
535 void AstTyper::VisitCallNew(CallNew* expr) {
537 expr->RecordTypeFeedback(
oracle());
539 RECURSE(Visit(expr->expression()));
540 ZoneList<Expression*>* args = expr->arguments();
541 for (
int i = 0;
i < args->length(); ++
i) {
542 Expression* arg = args->at(
i);
550 void AstTyper::VisitCallRuntime(CallRuntime* expr) {
551 ZoneList<Expression*>* args = expr->arguments();
552 for (
int i = 0;
i < args->length(); ++
i) {
553 Expression* arg = args->at(
i);
561 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
565 expr->expression()->RecordToBooleanTypeFeedback(
oracle());
568 RECURSE(Visit(expr->expression()));
570 switch (expr->op()) {
587 void AstTyper::VisitCountOperation(CountOperation* expr) {
589 TypeFeedbackId store_id = expr->CountStoreFeedbackId();
590 expr->set_store_mode(
oracle()->GetStoreMode(store_id));
592 expr->set_type(
oracle()->CountType(expr->CountBinOpFeedbackId()));
595 RECURSE(Visit(expr->expression()));
599 VariableProxy* proxy = expr->expression()->AsVariableProxy();
600 if (proxy !=
NULL && proxy->var()->IsStackAllocated()) {
606 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
611 Maybe<int> fixed_right_arg;
612 Handle<AllocationSite> allocation_site;
614 &left_type, &right_type, &type, &fixed_right_arg,
615 &allocation_site, expr->op());
619 expr->set_allocation_site(allocation_site);
620 expr->set_fixed_right_arg(fixed_right_arg);
622 expr->left()->RecordToBooleanTypeFeedback(
oracle());
625 switch (expr->op()) {
639 left_effects.Alt(right_effects);
643 expr->left()->bounds(), expr->right()->bounds(), zone()));
647 case Token::BIT_AND: {
651 expr->left()->bounds().upper, expr->right()->bounds().upper, zone());
652 if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone());
663 Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())));
676 Bounds l = expr->left()->bounds();
677 Bounds r = expr->right()->bounds();
679 !l.lower->
IsInhabited() || !r.lower->IsInhabited() ?
681 l.lower->
Is(
Type::String()) || r.lower->
Is(
Type::String()) ?
682 Type::String(zone()) :
683 l.lower->
Is(
Type::Number()) && r.lower->
Is(
Type::Number()) ?
686 l.upper->
Is(Type::String()) || r.upper->Is(Type::String()) ?
687 Type::String(zone()) :
688 l.upper->
Is(
Type::Number()) && r.upper->
Is(
Type::Number()) ?
689 Type::Number(zone()) :
Type::NumberOrString(zone());
707 void AstTyper::VisitCompareOperation(CompareOperation* expr) {
713 &left_type, &right_type, &combined_type);
716 expr->set_combined_type(combined_type);
725 void AstTyper::VisitThisFunction(ThisFunction* expr) {
729 void AstTyper::VisitSuperReference(SuperReference* expr) {}
733 for (
int i = 0;
i < decls->length(); ++
i) {
740 void AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) {
744 void AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
745 RECURSE(Visit(declaration->fun()));
749 void AstTyper::VisitModuleDeclaration(ModuleDeclaration* declaration) {
750 RECURSE(Visit(declaration->module()));
754 void AstTyper::VisitImportDeclaration(ImportDeclaration* declaration) {
755 RECURSE(Visit(declaration->module()));
759 void AstTyper::VisitExportDeclaration(ExportDeclaration* declaration) {
763 void AstTyper::VisitModuleLiteral(ModuleLiteral* module) {
764 RECURSE(Visit(module->body()));
768 void AstTyper::VisitModuleVariable(ModuleVariable* module) {
772 void AstTyper::VisitModulePath(ModulePath* module) {
773 RECURSE(Visit(module->module()));
777 void AstTyper::VisitModuleUrl(ModuleUrl* module) {
781 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) {
void NarrowType(Expression *e, Bounds b)
int parameter_index(int index)
int variable_index(Variable *var)
void ObserveTypesAtOsrEntry(IterationStatement *stmt)
v8::internal::Effects< int, kNoVar > Effects
void NarrowLowerType(Expression *e, Type *t)
AstTyper(CompilationInfo *info)
Effect ObservedOnStack(Object *value)
TypeFeedbackOracle * oracle()
static void Run(CompilationInfo *info)
void VisitStatements(ZoneList< Statement * > *statements)
int stack_local_index(int index)
void VisitDeclarations(ZoneList< Declaration * > *declarations)
BailoutId osr_ast_id() const
FunctionLiteral * function() const
Handle< JSFunction > closure() const
static bool IsCompileTimeValue(Expression *expression)
void Seq(Var var, Effect effect)
Bounds LookupBounds(Var var)
static Handle< T > cast(Handle< S > that)
BailoutId OsrEntryId() const
Object * receiver() const
Object * GetParameter(int index) const
JSFunction * function() const
int ContextLocalCount() const
int num_parameters() const
VariableDeclaration * function() const
void CollectStackAndContextLocals(ZoneList< Variable * > *stack_locals, ZoneList< Variable * > *context_locals)
bool is_function_scope() const
ZoneList< Declaration * > * declarations()
Variable * parameter(int index) const
int StackLocalCount() const
Object * GetExpression(int index) const
virtual bool IsJump() const
void KeyedPropertyReceiverTypes(TypeFeedbackId id, SmallMapList *receiver_types, bool *is_string)
void CompareType(TypeFeedbackId id, Type **left, Type **right, Type **combined)
void BinaryType(TypeFeedbackId id, Type **left, Type **right, Type **result, Maybe< int > *fixed_right_arg, Handle< AllocationSite > *allocation_site, Token::Value operation)
void CountReceiverTypes(TypeFeedbackId id, SmallMapList *receiver_types)
Handle< AllocationSite > GetCallAllocationSite(int slot)
void PropertyReceiverTypes(TypeFeedbackId id, Handle< String > name, SmallMapList *receiver_types)
void KeyedAssignmentReceiverTypes(TypeFeedbackId id, SmallMapList *receiver_types, KeyedAccessStoreMode *store_mode)
void AssignmentReceiverTypes(TypeFeedbackId id, Handle< String > name, SmallMapList *receiver_types)
static TypeHandle NowOf(i::Object *value, Region *region)
static TypeHandle Array(TypeHandle element, Region *region)
static TypeHandle Constant(i::Handle< i::Object > value, Region *region)
void PrintTo(OStream &os, PrintDimension dim=BOTH_DIMS)
static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region *reg)
static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region *reg)
Handle< String > name() const
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
TypeImpl< ZoneTypeConfig > Type
OStream & endl(OStream &os)
kSerializedDataOffset Object
Handle< T > handle(T *t, Isolate *isolate)
BoundsImpl< ZoneTypeConfig > Bounds
Debugger support for the V8 JavaScript engine.
static Handle< Value > Throw(Isolate *isolate, const char *message)
Handle< Primitive > Undefined(Isolate *isolate)
static BoundsImpl Either(BoundsImpl b1, BoundsImpl b2, Region *region)