| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_S390 | 5 #if V8_TARGET_ARCH_S390 |
| 6 | 6 |
| 7 #include "src/full-codegen/full-codegen.h" | 7 #include "src/full-codegen/full-codegen.h" |
| 8 #include "src/ast/compile-time-value.h" | 8 #include "src/ast/compile-time-value.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 1203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 context()->Plug(r2); | 1214 context()->Plug(r2); |
| 1215 break; | 1215 break; |
| 1216 } | 1216 } |
| 1217 | 1217 |
| 1218 case VariableLocation::PARAMETER: | 1218 case VariableLocation::PARAMETER: |
| 1219 case VariableLocation::LOCAL: | 1219 case VariableLocation::LOCAL: |
| 1220 case VariableLocation::CONTEXT: { | 1220 case VariableLocation::CONTEXT: { |
| 1221 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); | 1221 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); |
| 1222 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1222 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
| 1223 : "[ Stack variable"); | 1223 : "[ Stack variable"); |
| 1224 if (proxy->needs_hole_check()) { | 1224 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) { |
| 1225 // Throw a reference error when using an uninitialized let/const | 1225 // Throw a reference error when using an uninitialized let/const |
| 1226 // binding in harmony mode. | 1226 // binding in harmony mode. |
| 1227 Label done; | 1227 Label done; |
| 1228 GetVar(r2, var); | 1228 GetVar(r2, var); |
| 1229 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 1229 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
| 1230 __ bne(&done); | 1230 __ bne(&done); |
| 1231 __ mov(r2, Operand(var->name())); | 1231 __ mov(r2, Operand(var->name())); |
| 1232 __ push(r2); | 1232 __ push(r2); |
| 1233 __ CallRuntime(Runtime::kThrowReferenceError); | 1233 __ CallRuntime(Runtime::kThrowReferenceError); |
| 1234 __ bind(&done); | 1234 __ bind(&done); |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1649 // Deoptimization point in case the binary operation may have side effects. | 1649 // Deoptimization point in case the binary operation may have side effects. |
| 1650 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); | 1650 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); |
| 1651 } else { | 1651 } else { |
| 1652 VisitForAccumulatorValue(expr->value()); | 1652 VisitForAccumulatorValue(expr->value()); |
| 1653 } | 1653 } |
| 1654 | 1654 |
| 1655 SetExpressionPosition(expr); | 1655 SetExpressionPosition(expr); |
| 1656 | 1656 |
| 1657 // Store the value. | 1657 // Store the value. |
| 1658 switch (assign_type) { | 1658 switch (assign_type) { |
| 1659 case VARIABLE: | 1659 case VARIABLE: { |
| 1660 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1660 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1661 expr->op(), expr->AssignmentSlot()); | 1661 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
| 1662 proxy->hole_check_mode()); |
| 1662 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1663 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1663 context()->Plug(r2); | 1664 context()->Plug(r2); |
| 1664 break; | 1665 break; |
| 1666 } |
| 1665 case NAMED_PROPERTY: | 1667 case NAMED_PROPERTY: |
| 1666 EmitNamedPropertyAssignment(expr); | 1668 EmitNamedPropertyAssignment(expr); |
| 1667 break; | 1669 break; |
| 1668 case NAMED_SUPER_PROPERTY: | 1670 case NAMED_SUPER_PROPERTY: |
| 1669 EmitNamedSuperPropertyStore(property); | 1671 EmitNamedSuperPropertyStore(property); |
| 1670 context()->Plug(r2); | 1672 context()->Plug(r2); |
| 1671 break; | 1673 break; |
| 1672 case KEYED_SUPER_PROPERTY: | 1674 case KEYED_SUPER_PROPERTY: |
| 1673 EmitKeyedSuperPropertyStore(property); | 1675 EmitKeyedSuperPropertyStore(property); |
| 1674 context()->Plug(r2); | 1676 context()->Plug(r2); |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1979 | 1981 |
| 1980 void FullCodeGenerator::EmitAssignment(Expression* expr, | 1982 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 1981 FeedbackVectorSlot slot) { | 1983 FeedbackVectorSlot slot) { |
| 1982 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 1984 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
| 1983 | 1985 |
| 1984 Property* prop = expr->AsProperty(); | 1986 Property* prop = expr->AsProperty(); |
| 1985 LhsKind assign_type = Property::GetAssignType(prop); | 1987 LhsKind assign_type = Property::GetAssignType(prop); |
| 1986 | 1988 |
| 1987 switch (assign_type) { | 1989 switch (assign_type) { |
| 1988 case VARIABLE: { | 1990 case VARIABLE: { |
| 1989 Variable* var = expr->AsVariableProxy()->var(); | 1991 VariableProxy* proxy = expr->AsVariableProxy(); |
| 1990 EffectContext context(this); | 1992 EffectContext context(this); |
| 1991 EmitVariableAssignment(var, Token::ASSIGN, slot); | 1993 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot, |
| 1994 proxy->hole_check_mode()); |
| 1992 break; | 1995 break; |
| 1993 } | 1996 } |
| 1994 case NAMED_PROPERTY: { | 1997 case NAMED_PROPERTY: { |
| 1995 PushOperand(r2); // Preserve value. | 1998 PushOperand(r2); // Preserve value. |
| 1996 VisitForAccumulatorValue(prop->obj()); | 1999 VisitForAccumulatorValue(prop->obj()); |
| 1997 __ Move(StoreDescriptor::ReceiverRegister(), r2); | 2000 __ Move(StoreDescriptor::ReceiverRegister(), r2); |
| 1998 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 2001 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1999 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 2002 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
| 2000 break; | 2003 break; |
| 2001 } | 2004 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2056 if (var->IsContextSlot()) { | 2059 if (var->IsContextSlot()) { |
| 2057 // RecordWrite may destroy all its register arguments. | 2060 // RecordWrite may destroy all its register arguments. |
| 2058 __ LoadRR(r5, result_register()); | 2061 __ LoadRR(r5, result_register()); |
| 2059 int offset = Context::SlotOffset(var->index()); | 2062 int offset = Context::SlotOffset(var->index()); |
| 2060 __ RecordWriteContextSlot(r3, offset, r5, r4, kLRHasBeenSaved, | 2063 __ RecordWriteContextSlot(r3, offset, r5, r4, kLRHasBeenSaved, |
| 2061 kDontSaveFPRegs); | 2064 kDontSaveFPRegs); |
| 2062 } | 2065 } |
| 2063 } | 2066 } |
| 2064 | 2067 |
| 2065 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2068 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2066 FeedbackVectorSlot slot) { | 2069 FeedbackVectorSlot slot, |
| 2070 HoleCheckMode hole_check_mode) { |
| 2067 if (var->IsUnallocated()) { | 2071 if (var->IsUnallocated()) { |
| 2068 // Global var, const, or let. | 2072 // Global var, const, or let. |
| 2069 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); | 2073 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); |
| 2070 CallStoreIC(slot, var->name()); | 2074 CallStoreIC(slot, var->name()); |
| 2071 | 2075 |
| 2072 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { | 2076 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { |
| 2073 // Non-initializing assignment to let variable needs a write barrier. | 2077 // Non-initializing assignment to let variable needs a write barrier. |
| 2074 DCHECK(!var->IsLookupSlot()); | 2078 DCHECK(!var->IsLookupSlot()); |
| 2075 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2079 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2076 MemOperand location = VarOperand(var, r3); | 2080 MemOperand location = VarOperand(var, r3); |
| 2077 // Perform an initialization check for lexically declared variables. | 2081 // Perform an initialization check for lexically declared variables. |
| 2078 if (var->binding_needs_init()) { | 2082 if (hole_check_mode == HoleCheckMode::kRequired) { |
| 2079 Label assign; | 2083 Label assign; |
| 2080 __ LoadP(r5, location); | 2084 __ LoadP(r5, location); |
| 2081 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | 2085 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); |
| 2082 __ bne(&assign); | 2086 __ bne(&assign); |
| 2083 __ mov(r5, Operand(var->name())); | 2087 __ mov(r5, Operand(var->name())); |
| 2084 __ push(r5); | 2088 __ push(r5); |
| 2085 __ CallRuntime(Runtime::kThrowReferenceError); | 2089 __ CallRuntime(Runtime::kThrowReferenceError); |
| 2086 __ bind(&assign); | 2090 __ bind(&assign); |
| 2087 } | 2091 } |
| 2088 if (var->mode() != CONST) { | 2092 if (var->mode() != CONST) { |
| (...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3106 | 3110 |
| 3107 SetExpressionPosition(expr); | 3111 SetExpressionPosition(expr); |
| 3108 | 3112 |
| 3109 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code(); | 3113 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code(); |
| 3110 CallIC(code, expr->CountBinOpFeedbackId()); | 3114 CallIC(code, expr->CountBinOpFeedbackId()); |
| 3111 patch_site.EmitPatchInfo(); | 3115 patch_site.EmitPatchInfo(); |
| 3112 __ bind(&done); | 3116 __ bind(&done); |
| 3113 | 3117 |
| 3114 // Store the value returned in r2. | 3118 // Store the value returned in r2. |
| 3115 switch (assign_type) { | 3119 switch (assign_type) { |
| 3116 case VARIABLE: | 3120 case VARIABLE: { |
| 3121 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 3117 if (expr->is_postfix()) { | 3122 if (expr->is_postfix()) { |
| 3118 { | 3123 { |
| 3119 EffectContext context(this); | 3124 EffectContext context(this); |
| 3120 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3125 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), |
| 3121 Token::ASSIGN, expr->CountSlot()); | 3126 proxy->hole_check_mode()); |
| 3122 PrepareForBailoutForId(expr->AssignmentId(), | 3127 PrepareForBailoutForId(expr->AssignmentId(), |
| 3123 BailoutState::TOS_REGISTER); | 3128 BailoutState::TOS_REGISTER); |
| 3124 context.Plug(r2); | 3129 context.Plug(r2); |
| 3125 } | 3130 } |
| 3126 // For all contexts except EffectConstant We have the result on | 3131 // For all contexts except EffectConstant We have the result on |
| 3127 // top of the stack. | 3132 // top of the stack. |
| 3128 if (!context()->IsEffect()) { | 3133 if (!context()->IsEffect()) { |
| 3129 context()->PlugTOS(); | 3134 context()->PlugTOS(); |
| 3130 } | 3135 } |
| 3131 } else { | 3136 } else { |
| 3132 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3137 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), |
| 3133 Token::ASSIGN, expr->CountSlot()); | 3138 proxy->hole_check_mode()); |
| 3134 PrepareForBailoutForId(expr->AssignmentId(), | 3139 PrepareForBailoutForId(expr->AssignmentId(), |
| 3135 BailoutState::TOS_REGISTER); | 3140 BailoutState::TOS_REGISTER); |
| 3136 context()->Plug(r2); | 3141 context()->Plug(r2); |
| 3137 } | 3142 } |
| 3138 break; | 3143 break; |
| 3144 } |
| 3139 case NAMED_PROPERTY: { | 3145 case NAMED_PROPERTY: { |
| 3140 PopOperand(StoreDescriptor::ReceiverRegister()); | 3146 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 3141 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); | 3147 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); |
| 3142 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 3148 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 3143 if (expr->is_postfix()) { | 3149 if (expr->is_postfix()) { |
| 3144 if (!context()->IsEffect()) { | 3150 if (!context()->IsEffect()) { |
| 3145 context()->PlugTOS(); | 3151 context()->PlugTOS(); |
| 3146 } | 3152 } |
| 3147 } else { | 3153 } else { |
| 3148 context()->Plug(r2); | 3154 context()->Plug(r2); |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3539 DCHECK(kOSRBranchInstruction == br_instr); | 3545 DCHECK(kOSRBranchInstruction == br_instr); |
| 3540 | 3546 |
| 3541 DCHECK(interrupt_address == | 3547 DCHECK(interrupt_address == |
| 3542 isolate->builtins()->OnStackReplacement()->entry()); | 3548 isolate->builtins()->OnStackReplacement()->entry()); |
| 3543 return ON_STACK_REPLACEMENT; | 3549 return ON_STACK_REPLACEMENT; |
| 3544 } | 3550 } |
| 3545 | 3551 |
| 3546 } // namespace internal | 3552 } // namespace internal |
| 3547 } // namespace v8 | 3553 } // namespace v8 |
| 3548 #endif // V8_TARGET_ARCH_S390 | 3554 #endif // V8_TARGET_ARCH_S390 |
| OLD | NEW |