diff options
Diffstat (limited to 'deps/v8/src/full-codegen/full-codegen.cc')
-rw-r--r-- | deps/v8/src/full-codegen/full-codegen.cc | 171 |
1 files changed, 142 insertions, 29 deletions
diff --git a/deps/v8/src/full-codegen/full-codegen.cc b/deps/v8/src/full-codegen/full-codegen.cc index d83a23b3f8..25d7f920f1 100644 --- a/deps/v8/src/full-codegen/full-codegen.cc +++ b/deps/v8/src/full-codegen/full-codegen.cc @@ -10,6 +10,7 @@ #include "src/ast/scopes.h" #include "src/code-factory.h" #include "src/codegen.h" +#include "src/compilation-info.h" #include "src/compiler.h" #include "src/debug/debug.h" #include "src/debug/liveedit.h" @@ -25,15 +26,69 @@ namespace internal { #define __ ACCESS_MASM(masm()) +class FullCodegenCompilationJob final : public CompilationJob { + public: + explicit FullCodegenCompilationJob(CompilationInfo* info) + : CompilationJob(info->isolate(), info, "Full-Codegen") {} + + bool can_execute_on_background_thread() const override { return false; } + + CompilationJob::Status PrepareJobImpl() final { return SUCCEEDED; } + + CompilationJob::Status ExecuteJobImpl() final { + DCHECK(ThreadId::Current().Equals(isolate()->thread_id())); + return FullCodeGenerator::MakeCode(info(), stack_limit()) ? SUCCEEDED + : FAILED; + } + + CompilationJob::Status FinalizeJobImpl() final { return SUCCEEDED; } +}; + +FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm, + CompilationInfo* info, + uintptr_t stack_limit) + : masm_(masm), + info_(info), + isolate_(info->isolate()), + zone_(info->zone()), + scope_(info->scope()), + nesting_stack_(NULL), + loop_depth_(0), + operand_stack_depth_(0), + globals_(NULL), + context_(NULL), + bailout_entries_(info->HasDeoptimizationSupport() + ? info->literal()->ast_node_count() + : 0, + info->zone()), + back_edges_(2, info->zone()), + handler_table_(info->zone()), + source_position_table_builder_(info->zone(), + info->SourcePositionRecordingMode()), + ic_total_count_(0) { + DCHECK(!info->IsStub()); + Initialize(stack_limit); +} + +// static +CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info) { + return new FullCodegenCompilationJob(info); +} + +// static bool FullCodeGenerator::MakeCode(CompilationInfo* info) { + return MakeCode(info, info->isolate()->stack_guard()->real_climit()); +} + +// static +bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) { Isolate* isolate = info->isolate(); DCHECK(!FLAG_minimal); RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileFullCode); TimerEventScope<TimerEventCompileFullCode> timer(info->isolate()); - TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED( - isolate, &tracing::TraceEventStatsTable::CompileFullCode); + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileFullCode"); Handle<Script> script = info->script(); if (!script->IsUndefined(isolate) && @@ -47,7 +102,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) { CodeObjectRequired::kYes); if (info->will_serialize()) masm.enable_serializer(); - FullCodeGenerator cgen(&masm, info); + FullCodeGenerator cgen(&masm, info, stack_limit); cgen.Generate(); if (cgen.HasStackOverflow()) { DCHECK(!isolate->has_pending_exception()); @@ -157,9 +212,8 @@ bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime( expr->values()->length() > JSArray::kInitialMaxFastElementArray; } - -void FullCodeGenerator::Initialize() { - InitializeAstVisitor(info_->isolate()); +void FullCodeGenerator::Initialize(uintptr_t stack_limit) { + InitializeAstVisitor(stack_limit); masm_->set_emit_debug_code(FLAG_debug_code); masm_->set_predictable_code_size(true); } @@ -169,23 +223,52 @@ void FullCodeGenerator::PrepareForBailout(Expression* node, PrepareForBailoutForId(node->id(), state); } -void FullCodeGenerator::CallLoadIC(TypeFeedbackId id) { +void FullCodeGenerator::CallLoadIC(FeedbackVectorSlot slot, Handle<Object> name, + TypeFeedbackId id) { + DCHECK(name->IsName()); + __ Move(LoadDescriptor::NameRegister(), name); + + EmitLoadSlot(LoadDescriptor::SlotRegister(), slot); + Handle<Code> ic = CodeFactory::LoadIC(isolate()).code(); CallIC(ic, id); if (FLAG_tf_load_ic_stub) RestoreContext(); } -void FullCodeGenerator::CallLoadGlobalIC(TypeofMode typeof_mode, - TypeFeedbackId id) { - Handle<Code> ic = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code(); - CallIC(ic, id); -} +void FullCodeGenerator::CallStoreIC(FeedbackVectorSlot slot, + Handle<Object> name, TypeFeedbackId id) { + DCHECK(name->IsName()); + __ Move(StoreDescriptor::NameRegister(), name); + + STATIC_ASSERT(!StoreDescriptor::kPassLastArgsOnStack || + StoreDescriptor::kStackArgumentsCount == 2); + if (StoreDescriptor::kPassLastArgsOnStack) { + __ Push(StoreDescriptor::ValueRegister()); + EmitPushSlot(slot); + } else { + EmitLoadSlot(StoreDescriptor::SlotRegister(), slot); + } -void FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code(); CallIC(ic, id); + RestoreContext(); } +void FullCodeGenerator::CallKeyedStoreIC(FeedbackVectorSlot slot) { + STATIC_ASSERT(!StoreDescriptor::kPassLastArgsOnStack || + StoreDescriptor::kStackArgumentsCount == 2); + if (StoreDescriptor::kPassLastArgsOnStack) { + __ Push(StoreDescriptor::ValueRegister()); + EmitPushSlot(slot); + } else { + EmitLoadSlot(StoreDescriptor::SlotRegister(), slot); + } + + Handle<Code> ic = + CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); + CallIC(ic); + RestoreContext(); +} void FullCodeGenerator::RecordJSReturnSite(Call* call) { // We record the offset of the function return so we can rebuild the frame @@ -411,6 +494,18 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { EmitVariableLoad(expr); } +void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, + TypeofMode typeof_mode) { +#ifdef DEBUG + Variable* var = proxy->var(); + DCHECK(var->IsUnallocated() || + (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); +#endif + EmitLoadSlot(LoadGlobalDescriptor::SlotRegister(), + proxy->VariableFeedbackSlot()); + Handle<Code> ic = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code(); + CallIC(ic); +} void FullCodeGenerator::VisitSloppyBlockFunctionStatement( SloppyBlockFunctionStatement* declaration) { @@ -473,6 +568,7 @@ void FullCodeGenerator::EmitSubString(CallRuntime* expr) { VisitForStackValue(args->at(1)); VisitForStackValue(args->at(2)); __ CallStub(&stub); + RestoreContext(); OperandStackDepthDecrement(3); context()->Plug(result_register()); } @@ -816,8 +912,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { DCHECK(!context()->IsEffect()); DCHECK(!context()->IsTest()); - if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() || - proxy->var()->IsLookupSlot())) { + if (proxy != NULL && + (proxy->var()->IsUnallocated() || proxy->var()->IsLookupSlot())) { EmitVariableLoad(proxy, INSIDE_TYPEOF); PrepareForBailout(proxy, BailoutState::TOS_REGISTER); } else { @@ -896,6 +992,7 @@ void FullCodeGenerator::EmitContinue(Statement* target) { // accumulator on the stack. ClearAccumulator(); while (!current->IsContinueTarget(target)) { + if (HasStackOverflow()) return; if (current->IsTryFinally()) { Comment cmnt(masm(), "[ Deferred continue through finally"); current->Exit(&context_length); @@ -936,6 +1033,7 @@ void FullCodeGenerator::EmitBreak(Statement* target) { // accumulator on the stack. ClearAccumulator(); while (!current->IsBreakTarget(target)) { + if (HasStackOverflow()) return; if (current->IsTryFinally()) { Comment cmnt(masm(), "[ Deferred break through finally"); current->Exit(&context_length); @@ -971,6 +1069,7 @@ void FullCodeGenerator::EmitUnwindAndReturn() { NestedStatement* current = nesting_stack_; int context_length = 0; while (current != NULL) { + if (HasStackOverflow()) return; if (current->IsTryFinally()) { Comment cmnt(masm(), "[ Deferred return through finally"); current->Exit(&context_length); @@ -1008,10 +1107,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { DCHECK(!key->value()->IsSmi()); DCHECK(!prop->IsSuperAccess()); - __ Move(LoadDescriptor::NameRegister(), key->value()); - __ Move(LoadDescriptor::SlotRegister(), - SmiFromSlot(prop->PropertyFeedbackSlot())); - CallLoadIC(); + CallLoadIC(prop->PropertyFeedbackSlot(), key->value()); } void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { @@ -1027,11 +1123,12 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { SetExpressionPosition(prop); + + EmitLoadSlot(LoadDescriptor::SlotRegister(), prop->PropertyFeedbackSlot()); + Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); - __ Move(LoadDescriptor::SlotRegister(), - SmiFromSlot(prop->PropertyFeedbackSlot())); CallIC(ic); - if (FLAG_tf_load_ic_stub) RestoreContext(); + RestoreContext(); } void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { @@ -1040,7 +1137,7 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); } -void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, +void FullCodeGenerator::EmitPropertyKey(LiteralProperty* property, BailoutId bailout_id) { VisitForStackValue(property->key()); CallRuntimeWithOperands(Runtime::kToName); @@ -1048,9 +1145,14 @@ void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, PushOperand(result_register()); } -void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { +void FullCodeGenerator::EmitLoadSlot(Register destination, + FeedbackVectorSlot slot) { DCHECK(!slot.IsInvalid()); - __ Move(StoreDescriptor::SlotRegister(), SmiFromSlot(slot)); + __ Move(destination, SmiFromSlot(slot)); +} + +void FullCodeGenerator::EmitPushSlot(FeedbackVectorSlot slot) { + __ Push(SmiFromSlot(slot)); } void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { @@ -1073,6 +1175,7 @@ void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { RestoreContext(); PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); PushOperand(result_register()); + PushOperand(stmt->scope()->scope_info()); PushFunctionArgumentForContextAllocation(); CallRuntimeWithOperands(Runtime::kPushWithContext); StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); @@ -1274,6 +1377,7 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { { Comment cmnt(masm_, "[ Extend catch context"); PushOperand(stmt->variable()->name()); PushOperand(result_register()); + PushOperand(stmt->scope()->scope_info()); PushFunctionArgumentForContextAllocation(); CallRuntimeWithOperands(Runtime::kPushCatchContext); StoreToFrameField(StandardFrameConstants::kContextOffset, @@ -1466,9 +1570,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { // Load the "prototype" from the constructor. __ Move(LoadDescriptor::ReceiverRegister(), result_register()); - __ LoadRoot(LoadDescriptor::NameRegister(), Heap::kprototype_stringRootIndex); - __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); - CallLoadIC(); + CallLoadIC(lit->PrototypeSlot(), isolate()->factory()->prototype_string()); PrepareForBailoutForId(lit->PrototypeId(), BailoutState::TOS_REGISTER); PushOperand(result_register()); @@ -1847,7 +1949,7 @@ FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded( { if (needs_block_context_) { Comment cmnt(masm(), "[ Extend block context"); - codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate())); + codegen_->PushOperand(scope->scope_info()); codegen_->PushFunctionArgumentForContextAllocation(); codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext); @@ -1939,6 +2041,17 @@ bool FullCodeGenerator::NeedsHoleCheckForLoad(VariableProxy* proxy) { var->initializer_position() >= proxy->position(); } +Handle<Script> FullCodeGenerator::script() { return info_->script(); } + +LanguageMode FullCodeGenerator::language_mode() { + return scope()->language_mode(); +} + +bool FullCodeGenerator::has_simple_parameters() { + return info_->has_simple_parameters(); +} + +FunctionLiteral* FullCodeGenerator::literal() const { return info_->literal(); } #undef __ |