diff options
Diffstat (limited to 'deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc')
-rw-r--r-- | deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc | 177 |
1 files changed, 50 insertions, 127 deletions
diff --git a/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc b/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc index 6813069d40..de9a8f46cf 100644 --- a/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc +++ b/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc @@ -4,14 +4,16 @@ #if V8_TARGET_ARCH_PPC +#include "src/full-codegen/full-codegen.h" +#include "src/ast/compile-time-value.h" #include "src/ast/scopes.h" #include "src/code-factory.h" #include "src/code-stubs.h" #include "src/codegen.h" +#include "src/compilation-info.h" +#include "src/compiler.h" #include "src/debug/debug.h" -#include "src/full-codegen/full-codegen.h" #include "src/ic/ic.h" -#include "src/parsing/parser.h" #include "src/ppc/code-stubs-ppc.h" #include "src/ppc/macro-assembler-ppc.h" @@ -131,6 +133,22 @@ void FullCodeGenerator::Generate() { info->set_prologue_offset(prologue_offset); __ Prologue(info->GeneratePreagedPrologue(), ip, prologue_offset); + // Increment invocation count for the function. + { + Comment cmnt(masm_, "[ Increment invocation count"); + __ LoadP(r7, FieldMemOperand(r4, JSFunction::kLiteralsOffset)); + __ LoadP(r7, FieldMemOperand(r7, LiteralsArray::kFeedbackVectorOffset)); + __ LoadP(r8, FieldMemOperand(r7, TypeFeedbackVector::kInvocationCountIndex * + kPointerSize + + TypeFeedbackVector::kHeaderSize)); + __ AddSmiLiteral(r8, r8, Smi::FromInt(1), r0); + __ StoreP(r8, + FieldMemOperand( + r7, TypeFeedbackVector::kInvocationCountIndex * kPointerSize + + TypeFeedbackVector::kHeaderSize), + r0); + } + { Comment cmnt(masm_, "[ Allocate locals"); int locals_count = info->scope()->num_stack_slots(); @@ -173,14 +191,14 @@ void FullCodeGenerator::Generate() { bool function_in_register_r4 = true; // Possibly allocate a local context. - if (info->scope()->num_heap_slots() > 0) { + if (info->scope()->NeedsContext()) { // Argument to NewContext is the function, which is still in r4. Comment cmnt(masm_, "[ Allocate context"); bool need_write_barrier = true; int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; if (info->scope()->is_script_scope()) { __ push(r4); - __ Push(info->scope()->GetScopeInfo(info->isolate())); + __ Push(info->scope()->scope_info()); __ CallRuntime(Runtime::kNewScriptContext); PrepareForBailoutForId(BailoutId::ScriptContext(), BailoutState::TOS_REGISTER); @@ -265,9 +283,8 @@ void FullCodeGenerator::Generate() { } // Possibly allocate RestParameters - int rest_index; - Variable* rest_param = info->scope()->rest_parameter(&rest_index); - if (rest_param) { + Variable* rest_param = info->scope()->rest_parameter(); + if (rest_param != nullptr) { Comment cmnt(masm_, "[ Allocate rest parameter array"); if (!function_in_register_r4) { __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); @@ -732,7 +749,6 @@ void FullCodeGenerator::VisitVariableDeclaration( VariableProxy* proxy = declaration->proxy(); Variable* variable = proxy->var(); switch (variable->location()) { - case VariableLocation::GLOBAL: case VariableLocation::UNALLOCATED: { DCHECK(!variable->binding_needs_init()); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); @@ -783,7 +799,6 @@ void FullCodeGenerator::VisitFunctionDeclaration( VariableProxy* proxy = declaration->proxy(); Variable* variable = proxy->var(); switch (variable->location()) { - case VariableLocation::GLOBAL: case VariableLocation::UNALLOCATED: { FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); DCHECK(!slot.IsInvalid()); @@ -1102,6 +1117,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Generate code for the going to the next element by incrementing // the index (smi) stored on top of the stack. __ bind(loop_statement.continue_label()); + PrepareForBailoutForId(stmt->IncrementId(), BailoutState::NO_REGISTERS); __ pop(r3); __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0); __ push(r3); @@ -1124,12 +1140,9 @@ void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, FeedbackVectorSlot slot) { DCHECK(NeedsHomeObject(initializer)); __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); - __ mov(StoreDescriptor::NameRegister(), - Operand(isolate()->factory()->home_object_symbol())); __ LoadP(StoreDescriptor::ValueRegister(), MemOperand(sp, offset * kPointerSize)); - EmitLoadStoreICSlot(slot); - CallStoreIC(); + CallStoreIC(slot, isolate()->factory()->home_object_symbol()); } @@ -1138,12 +1151,9 @@ void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, FeedbackVectorSlot slot) { DCHECK(NeedsHomeObject(initializer)); __ Move(StoreDescriptor::ReceiverRegister(), r3); - __ mov(StoreDescriptor::NameRegister(), - Operand(isolate()->factory()->home_object_symbol())); __ LoadP(StoreDescriptor::ValueRegister(), MemOperand(sp, offset * kPointerSize)); - EmitLoadStoreICSlot(slot); - CallStoreIC(); + CallStoreIC(slot, isolate()->factory()->home_object_symbol()); } @@ -1183,7 +1193,7 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, Register temp = r7; for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { - if (s->num_heap_slots() > 0) { + if (s->NeedsContext()) { if (s->calls_sloppy_eval()) { // Check that extension is "the hole". __ LoadP(temp, ContextMemOperand(context, Context::EXTENSION_INDEX)); @@ -1232,20 +1242,6 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, } } - -void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, - TypeofMode typeof_mode) { -#ifdef DEBUG - Variable* var = proxy->var(); - DCHECK(var->IsUnallocatedOrGlobalSlot() || - (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); -#endif - __ mov(LoadGlobalDescriptor::SlotRegister(), - Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); - CallLoadGlobalIC(typeof_mode); -} - - void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { // Record position before possible IC call. @@ -1256,7 +1252,6 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, // Three cases: global variables, lookup variables, and all other types of // variables. switch (var->location()) { - case VariableLocation::GLOBAL: case VariableLocation::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); EmitGlobalVariableLoad(proxy, typeof_mode); @@ -1379,10 +1374,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { if (property->emit_store()) { VisitForAccumulatorValue(value); DCHECK(StoreDescriptor::ValueRegister().is(r3)); - __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); - EmitLoadStoreICSlot(property->GetSlot(0)); - CallStoreIC(); + CallStoreIC(property->GetSlot(0), key->value()); PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); if (NeedsHomeObject(value)) { @@ -1552,6 +1545,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { } else { FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); __ CallStub(&stub); + RestoreContext(); } PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); @@ -1561,8 +1555,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { // Emit code to evaluate all the non-constant subexpressions and to store // them into the newly cloned array. - int array_index = 0; - for (; array_index < length; array_index++) { + for (int array_index = 0; array_index < length; array_index++) { Expression* subexpr = subexprs->at(array_index); DCHECK(!subexpr->IsSpread()); // If the subexpression is a literal or a simple materialized literal it @@ -1578,31 +1571,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { __ LoadSmiLiteral(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); - EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); - Handle<Code> ic = - CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); - CallIC(ic); - - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); - } - - // In case the array literal contains spread expressions it has two parts. The - // first part is the "static" array which has a literal index is handled - // above. The second part is the part after the first spread expression - // (inclusive) and these elements gets appended to the array. Note that the - // number elements an iterable produces is unknown ahead of time. - if (array_index < length && result_saved) { - PopOperand(r3); - result_saved = false; - } - for (; array_index < length; array_index++) { - Expression* subexpr = subexprs->at(array_index); - - PushOperand(r3); - DCHECK(!subexpr->IsSpread()); - VisitForStackValue(subexpr); - CallRuntimeWithOperands(Runtime::kAppendElement); + CallKeyedStoreIC(expr->LiteralFeedbackSlot()); PrepareForBailoutForId(expr->GetIdForElement(array_index), BailoutState::NO_REGISTERS); @@ -1998,7 +1967,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { for (int i = 0; i < lit->properties()->length(); i++) { - ObjectLiteral::Property* property = lit->properties()->at(i); + ClassLiteral::Property* property = lit->properties()->at(i); Expression* value = property->value(); Register scratch = r4; @@ -2025,26 +1994,23 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { } switch (property->kind()) { - case ObjectLiteral::Property::CONSTANT: - case ObjectLiteral::Property::MATERIALIZED_LITERAL: - case ObjectLiteral::Property::PROTOTYPE: - UNREACHABLE(); - case ObjectLiteral::Property::COMPUTED: + case ClassLiteral::Property::METHOD: PushOperand(Smi::FromInt(DONT_ENUM)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); break; - case ObjectLiteral::Property::GETTER: + case ClassLiteral::Property::GETTER: PushOperand(Smi::FromInt(DONT_ENUM)); CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); break; - case ObjectLiteral::Property::SETTER: + case ClassLiteral::Property::SETTER: PushOperand(Smi::FromInt(DONT_ENUM)); CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); break; + case ClassLiteral::Property::FIELD: default: UNREACHABLE(); } @@ -2081,10 +2047,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, VisitForAccumulatorValue(prop->obj()); __ Move(StoreDescriptor::ReceiverRegister(), r3); PopOperand(StoreDescriptor::ValueRegister()); // Restore value. - __ mov(StoreDescriptor::NameRegister(), - Operand(prop->key()->AsLiteral()->value())); - EmitLoadStoreICSlot(slot); - CallStoreIC(); + CallStoreIC(slot, prop->key()->AsLiteral()->value()); break; } case NAMED_SUPER_PROPERTY: { @@ -2131,10 +2094,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, __ Move(StoreDescriptor::NameRegister(), r3); PopOperands(StoreDescriptor::ValueRegister(), StoreDescriptor::ReceiverRegister()); - EmitLoadStoreICSlot(slot); - Handle<Code> ic = - CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); - CallIC(ic); + CallKeyedStoreIC(slot); break; } } @@ -2159,10 +2119,8 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, FeedbackVectorSlot slot) { if (var->IsUnallocated()) { // Global var, const, or let. - __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); - EmitLoadStoreICSlot(slot); - CallStoreIC(); + CallStoreIC(slot, var->name()); } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { DCHECK(!var->IsLookupSlot()); @@ -2179,10 +2137,10 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, __ CallRuntime(Runtime::kThrowReferenceError); __ bind(&assign); } - if (var->mode() == CONST) { - __ CallRuntime(Runtime::kThrowConstAssignError); - } else { + if (var->mode() != CONST) { EmitStoreToStackLocalOrContextSlot(var, location); + } else if (var->throw_on_const_assignment(language_mode())) { + __ CallRuntime(Runtime::kThrowConstAssignError); } } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { // Initializing assignment to const {this} needs a write barrier. @@ -2198,7 +2156,8 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, __ bind(&uninitialized_this); EmitStoreToStackLocalOrContextSlot(var, location); - } else if (!var->is_const_mode() || op == Token::INIT) { + } else { + DCHECK(var->mode() != CONST || op == Token::INIT); if (var->IsLookupSlot()) { // Assignment to var. __ Push(var->name()); @@ -2219,12 +2178,6 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, } EmitStoreToStackLocalOrContextSlot(var, location); } - } else { - DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); - if (is_strict(language_mode())) { - __ CallRuntime(Runtime::kThrowConstAssignError); - } - // Silently ignore store in sloppy mode. } } @@ -2235,11 +2188,8 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { DCHECK(prop != NULL); DCHECK(prop->key()->IsLiteral()); - __ mov(StoreDescriptor::NameRegister(), - Operand(prop->key()->AsLiteral()->value())); PopOperand(StoreDescriptor::ReceiverRegister()); - EmitLoadStoreICSlot(expr->AssignmentSlot()); - CallStoreIC(); + CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); context()->Plug(r3); @@ -2281,10 +2231,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { StoreDescriptor::NameRegister()); DCHECK(StoreDescriptor::ValueRegister().is(r3)); - Handle<Code> ic = - CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); - EmitLoadStoreICSlot(expr->AssignmentSlot()); - CallIC(ic); + CallKeyedStoreIC(expr->AssignmentSlot()); PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); context()->Plug(r3); @@ -2838,24 +2785,6 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) { } -void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - DCHECK(args->length() == 1); - VisitForAccumulatorValue(args->at(0)); - - Label done; - StringCharFromCodeGenerator generator(r3, r4); - generator.GenerateFast(masm_); - __ b(&done); - - NopRuntimeCallHelper call_helper; - generator.GenerateSlow(masm_, call_helper); - - __ bind(&done); - context()->Plug(r4); -} - - void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { ZoneList<Expression*>* args = expr->arguments(); DCHECK(args->length() == 2); @@ -3048,7 +2977,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { // "delete this" is allowed. bool is_this = var->is_this(); DCHECK(is_sloppy(language_mode()) || is_this); - if (var->IsUnallocatedOrGlobalSlot()) { + if (var->IsUnallocated()) { __ LoadGlobalObject(r5); __ mov(r4, Operand(var->name())); __ Push(r5, r4); @@ -3328,11 +3257,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } break; case NAMED_PROPERTY: { - __ mov(StoreDescriptor::NameRegister(), - Operand(prop->key()->AsLiteral()->value())); PopOperand(StoreDescriptor::ReceiverRegister()); - EmitLoadStoreICSlot(expr->CountSlot()); - CallStoreIC(); + CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); if (expr->is_postfix()) { if (!context()->IsEffect()) { @@ -3370,10 +3296,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { case KEYED_PROPERTY: { PopOperands(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); - Handle<Code> ic = - CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); - EmitLoadStoreICSlot(expr->CountSlot()); - CallIC(ic); + CallKeyedStoreIC(expr->CountSlot()); PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); if (expr->is_postfix()) { if (!context()->IsEffect()) { |