summaryrefslogtreecommitdiff
path: root/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc
diff options
context:
space:
mode:
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.cc177
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()) {