Index: src/full-codegen/s390/full-codegen-s390.cc |
diff --git a/src/full-codegen/s390/full-codegen-s390.cc b/src/full-codegen/s390/full-codegen-s390.cc |
index f17fb975bdae273ad6651a2e4b63aaf4a88414a2..98d2d7c2d02167c780ffa70607dc04c71dbbc2e9 100644 |
--- a/src/full-codegen/s390/full-codegen-s390.cc |
+++ b/src/full-codegen/s390/full-codegen-s390.cc |
@@ -309,9 +309,7 @@ void FullCodeGenerator::Generate() { |
// Visit the declarations and body unless there is an illegal |
// redeclaration. |
if (scope()->HasIllegalRedeclaration()) { |
- Comment cmnt(masm_, "[ Declarations"); |
- VisitForEffect(scope()->GetIllegalRedeclaration()); |
- |
+ EmitIllegalRedeclaration(); |
} else { |
PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
{ |
@@ -511,7 +509,7 @@ void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, |
false_label_); |
- DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); |
+ DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable()); |
if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { |
if (false_label_ != fall_through_) __ b(false_label_); |
} else if (lit->IsTrue() || lit->IsJSObject()) { |
@@ -602,7 +600,7 @@ void FullCodeGenerator::TestContext::Plug(bool flag) const { |
void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, |
Label* if_false, Label* fall_through) { |
- Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
+ Handle<Code> ic = ToBooleanICStub::GetUninitialized(isolate()); |
CallIC(ic, condition->test_id()); |
__ CompareRoot(result_register(), Heap::kTrueValueRootIndex); |
Split(eq, if_true, if_false, fall_through); |
@@ -1008,11 +1006,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
// We got a fixed array in register r2. Iterate through that. |
__ bind(&fixed_array); |
- int const vector_index = SmiFromSlot(slot)->value(); |
- __ EmitLoadTypeFeedbackVector(r3); |
- __ mov(r4, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
- __ StoreP( |
- r4, FieldMemOperand(r3, FixedArray::OffsetOfElementAt(vector_index)), r0); |
__ LoadSmiLiteral(r3, Smi::FromInt(1)); // Smi(1) indicates slow check |
__ Push(r3, r2); // Smi and array |
__ LoadP(r3, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
@@ -1049,12 +1042,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
__ CmpP(r6, r4); |
__ beq(&update_each); |
- // We might get here from TurboFan or Crankshaft when something in the |
- // for-in loop body deopts and only now notice in fullcodegen, that we |
- // can now longer use the enum cache, i.e. left fast mode. So better record |
- // this information here, in case we later OSR back into this loop or |
- // reoptimize the whole function w/o rerunning the loop with the slow |
- // mode object in fullcodegen (which would result in a deopt loop). |
+ // We need to filter the key, record slow-path here. |
+ int const vector_index = SmiFromSlot(slot)->value(); |
__ EmitLoadTypeFeedbackVector(r2); |
__ mov(r4, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
__ StoreP( |
@@ -1770,64 +1759,44 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
// this. It stays on the stack while we update the iterator. |
VisitForStackValue(expr->expression()); |
- switch (expr->yield_kind()) { |
- case Yield::kSuspend: |
- // Pop value from top-of-stack slot; box result into result register. |
- EmitCreateIteratorResult(false); |
- PushOperand(result_register()); |
- // Fall through. |
- case Yield::kInitial: { |
- Label suspend, continuation, post_runtime, resume; |
- |
- __ b(&suspend, Label::kNear); |
- __ bind(&continuation); |
- // When we arrive here, the stack top is the resume mode and |
- // result_register() holds the input value (the argument given to the |
- // respective resume operation). |
- __ RecordGeneratorContinuation(); |
- __ pop(r3); |
- __ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::RETURN), r0); |
- __ bne(&resume); |
- __ push(result_register()); |
- EmitCreateIteratorResult(true); |
- EmitUnwindAndReturn(); |
- |
- __ bind(&suspend); |
- OperandStackDepthIncrement(1); // Not popped on this path. |
- VisitForAccumulatorValue(expr->generator_object()); |
- DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
- __ LoadSmiLiteral(r3, Smi::FromInt(continuation.pos())); |
- __ StoreP(r3, |
- FieldMemOperand(r2, JSGeneratorObject::kContinuationOffset)); |
- __ StoreP(cp, FieldMemOperand(r2, JSGeneratorObject::kContextOffset)); |
- __ LoadRR(r3, cp); |
- __ RecordWriteField(r2, JSGeneratorObject::kContextOffset, r3, r4, |
- kLRHasBeenSaved, kDontSaveFPRegs); |
- __ AddP(r3, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
- __ CmpP(sp, r3); |
- __ beq(&post_runtime); |
- __ push(r2); // generator object |
- __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
- __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
- __ bind(&post_runtime); |
- PopOperand(result_register()); |
- EmitReturnSequence(); |
- |
- __ bind(&resume); |
- context()->Plug(result_register()); |
- break; |
- } |
- |
- case Yield::kFinal: { |
- // Pop value from top-of-stack slot, box result into result register. |
- EmitCreateIteratorResult(true); |
- EmitUnwindAndReturn(); |
- break; |
- } |
+ Label suspend, continuation, post_runtime, resume; |
+ |
+ __ b(&suspend); |
+ __ bind(&continuation); |
+ // When we arrive here, the stack top is the resume mode and |
+ // result_register() holds the input value (the argument given to the |
+ // respective resume operation). |
+ __ RecordGeneratorContinuation(); |
+ __ pop(r3); |
+ __ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::RETURN), r0); |
+ __ bne(&resume); |
+ __ push(result_register()); |
+ EmitCreateIteratorResult(true); |
+ EmitUnwindAndReturn(); |
+ |
+ __ bind(&suspend); |
+ OperandStackDepthIncrement(1); // Not popped on this path. |
+ VisitForAccumulatorValue(expr->generator_object()); |
+ DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
+ __ LoadSmiLiteral(r3, Smi::FromInt(continuation.pos())); |
+ __ StoreP(r3, FieldMemOperand(r2, JSGeneratorObject::kContinuationOffset), |
+ r0); |
+ __ StoreP(cp, FieldMemOperand(r2, JSGeneratorObject::kContextOffset), r0); |
+ __ LoadRR(r3, cp); |
+ __ RecordWriteField(r2, JSGeneratorObject::kContextOffset, r3, r4, |
+ kLRHasBeenSaved, kDontSaveFPRegs); |
+ __ AddP(r3, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
+ __ CmpP(sp, r3); |
+ __ beq(&post_runtime); |
+ __ push(r2); // generator object |
+ __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
+ __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ __ bind(&post_runtime); |
+ PopOperand(result_register()); |
+ EmitReturnSequence(); |
- case Yield::kDelegating: |
- UNREACHABLE(); |
- } |
+ __ bind(&resume); |
+ context()->Plug(result_register()); |
} |
void FullCodeGenerator::EmitGeneratorResume( |
@@ -1886,9 +1855,7 @@ void FullCodeGenerator::EmitGeneratorResume( |
// fp = caller's frame pointer. |
// cp = callee's context, |
// r6 = callee's JS function. |
- __ PushFixedFrame(r6); |
- // Adjust FP to point to saved FP. |
- __ lay(fp, MemOperand(sp, StandardFrameConstants::kFixedFrameSizeFromFp)); |
+ __ PushStandardFrame(r6); |
// Load the operand stack size. |
__ LoadP(r5, FieldMemOperand(r3, JSGeneratorObject::kOperandStackOffset)); |
@@ -3884,10 +3851,11 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, |
__ CompareRoot(r2, nil_value); |
Split(eq, if_true, if_false, fall_through); |
} else { |
- Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
- CallIC(ic, expr->CompareOperationFeedbackId()); |
- __ CompareRoot(r2, Heap::kTrueValueRootIndex); |
- Split(eq, if_true, if_false, fall_through); |
+ __ JumpIfSmi(r2, if_false); |
+ __ LoadP(r2, FieldMemOperand(r2, HeapObject::kMapOffset)); |
+ __ LoadlB(r3, FieldMemOperand(r2, Map::kBitFieldOffset)); |
+ __ AndP(r0, r3, Operand(1 << Map::kIsUndetectable)); |
+ Split(ne, if_true, if_false, fall_through); |
} |
context()->Plug(if_true, if_false); |
} |
@@ -3963,12 +3931,6 @@ void FullCodeGenerator::ClearPendingMessage() { |
__ StoreP(r3, MemOperand(ip)); |
} |
-void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { |
- DCHECK(!slot.IsInvalid()); |
- __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
- Operand(SmiFromSlot(slot))); |
-} |
- |
void FullCodeGenerator::DeferredCommands::EmitCommands() { |
DCHECK(!result_register().is(r3)); |
// Restore the accumulator (r2) and token (r3). |
@@ -4027,7 +3989,6 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc, |
break; |
} |
case ON_STACK_REPLACEMENT: |
- case OSR_AFTER_STACK_CHECK: |
// <decrement profiling counter> |
// brc 0x0, <ok> ;; patched to NOP BRC |
// brasrl r14, <interrupt stub address> |
@@ -4050,8 +4011,10 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( |
Isolate* isolate, Code* unoptimized_code, Address pc) { |
Address call_address = Assembler::target_address_from_return_address(pc); |
Address branch_address = call_address - 4; |
+#ifdef DEBUG |
Address interrupt_address = |
Assembler::target_address_at(call_address, unoptimized_code); |
+#endif |
DCHECK(BRC == Instruction::S390OpcodeValue(branch_address)); |
// For interrupt, we expect a branch greater than or equal |
@@ -4068,13 +4031,9 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( |
USE(kOSRBranchInstruction); |
DCHECK(kOSRBranchInstruction == br_instr); |
- if (interrupt_address == isolate->builtins()->OnStackReplacement()->entry()) { |
- return ON_STACK_REPLACEMENT; |
- } |
- |
DCHECK(interrupt_address == |
- isolate->builtins()->OsrAfterStackCheck()->entry()); |
- return OSR_AFTER_STACK_CHECK; |
+ isolate->builtins()->OnStackReplacement()->entry()); |
+ return ON_STACK_REPLACEMENT; |
} |
} // namespace internal |