Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(805)

Side by Side Diff: src/full-codegen/s390/full-codegen-s390.cc

Issue 1799893002: S390: Upstream changes from the past 2 weeks (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/debug/s390/debug-s390.cc ('k') | src/ic/s390/handler-compiler-s390.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 SetVar(arguments, r2, r3, r4); 302 SetVar(arguments, r2, r3, r4);
303 } 303 }
304 304
305 if (FLAG_trace) { 305 if (FLAG_trace) {
306 __ CallRuntime(Runtime::kTraceEnter); 306 __ CallRuntime(Runtime::kTraceEnter);
307 } 307 }
308 308
309 // Visit the declarations and body unless there is an illegal 309 // Visit the declarations and body unless there is an illegal
310 // redeclaration. 310 // redeclaration.
311 if (scope()->HasIllegalRedeclaration()) { 311 if (scope()->HasIllegalRedeclaration()) {
312 Comment cmnt(masm_, "[ Declarations"); 312 EmitIllegalRedeclaration();
313 VisitForEffect(scope()->GetIllegalRedeclaration());
314
315 } else { 313 } else {
316 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 314 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
317 { 315 {
318 Comment cmnt(masm_, "[ Declarations"); 316 Comment cmnt(masm_, "[ Declarations");
319 VisitDeclarations(scope()->declarations()); 317 VisitDeclarations(scope()->declarations());
320 } 318 }
321 319
322 // Assert that the declarations do not use ICs. Otherwise the debugger 320 // Assert that the declarations do not use ICs. Otherwise the debugger
323 // won't be able to redirect a PC at an IC to the correct IC in newly 321 // won't be able to redirect a PC at an IC to the correct IC in newly
324 // recompiled code. 322 // recompiled code.
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 502
505 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 503 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
506 // Immediates cannot be pushed directly. 504 // Immediates cannot be pushed directly.
507 __ mov(result_register(), Operand(lit)); 505 __ mov(result_register(), Operand(lit));
508 codegen()->PushOperand(result_register()); 506 codegen()->PushOperand(result_register());
509 } 507 }
510 508
511 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 509 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
512 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_, 510 codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
513 false_label_); 511 false_label_);
514 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectableObject()); 512 DCHECK(lit->IsNull() || lit->IsUndefined() || !lit->IsUndetectable());
515 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 513 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
516 if (false_label_ != fall_through_) __ b(false_label_); 514 if (false_label_ != fall_through_) __ b(false_label_);
517 } else if (lit->IsTrue() || lit->IsJSObject()) { 515 } else if (lit->IsTrue() || lit->IsJSObject()) {
518 if (true_label_ != fall_through_) __ b(true_label_); 516 if (true_label_ != fall_through_) __ b(true_label_);
519 } else if (lit->IsString()) { 517 } else if (lit->IsString()) {
520 if (String::cast(*lit)->length() == 0) { 518 if (String::cast(*lit)->length() == 0) {
521 if (false_label_ != fall_through_) __ b(false_label_); 519 if (false_label_ != fall_through_) __ b(false_label_);
522 } else { 520 } else {
523 if (true_label_ != fall_through_) __ b(true_label_); 521 if (true_label_ != fall_through_) __ b(true_label_);
524 } 522 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 false_label_); 593 false_label_);
596 if (flag) { 594 if (flag) {
597 if (true_label_ != fall_through_) __ b(true_label_); 595 if (true_label_ != fall_through_) __ b(true_label_);
598 } else { 596 } else {
599 if (false_label_ != fall_through_) __ b(false_label_); 597 if (false_label_ != fall_through_) __ b(false_label_);
600 } 598 }
601 } 599 }
602 600
603 void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, 601 void FullCodeGenerator::DoTest(Expression* condition, Label* if_true,
604 Label* if_false, Label* fall_through) { 602 Label* if_false, Label* fall_through) {
605 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 603 Handle<Code> ic = ToBooleanICStub::GetUninitialized(isolate());
606 CallIC(ic, condition->test_id()); 604 CallIC(ic, condition->test_id());
607 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); 605 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex);
608 Split(eq, if_true, if_false, fall_through); 606 Split(eq, if_true, if_false, fall_through);
609 } 607 }
610 608
611 void FullCodeGenerator::Split(Condition cond, Label* if_true, Label* if_false, 609 void FullCodeGenerator::Split(Condition cond, Label* if_true, Label* if_false,
612 Label* fall_through) { 610 Label* fall_through) {
613 if (if_false == fall_through) { 611 if (if_false == fall_through) {
614 __ b(cond, if_true); 612 __ b(cond, if_true);
615 } else if (if_true == fall_through) { 613 } else if (if_true == fall_through) {
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 __ Push(r4, r3, r2); 999 __ Push(r4, r3, r2);
1002 __ b(&loop); 1000 __ b(&loop);
1003 1001
1004 __ bind(&no_descriptors); 1002 __ bind(&no_descriptors);
1005 __ Drop(1); 1003 __ Drop(1);
1006 __ b(&exit); 1004 __ b(&exit);
1007 1005
1008 // We got a fixed array in register r2. Iterate through that. 1006 // We got a fixed array in register r2. Iterate through that.
1009 __ bind(&fixed_array); 1007 __ bind(&fixed_array);
1010 1008
1011 int const vector_index = SmiFromSlot(slot)->value();
1012 __ EmitLoadTypeFeedbackVector(r3);
1013 __ mov(r4, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1014 __ StoreP(
1015 r4, FieldMemOperand(r3, FixedArray::OffsetOfElementAt(vector_index)), r0);
1016 __ LoadSmiLiteral(r3, Smi::FromInt(1)); // Smi(1) indicates slow check 1009 __ LoadSmiLiteral(r3, Smi::FromInt(1)); // Smi(1) indicates slow check
1017 __ Push(r3, r2); // Smi and array 1010 __ Push(r3, r2); // Smi and array
1018 __ LoadP(r3, FieldMemOperand(r2, FixedArray::kLengthOffset)); 1011 __ LoadP(r3, FieldMemOperand(r2, FixedArray::kLengthOffset));
1019 __ Push(r3); // Fixed array length (as smi). 1012 __ Push(r3); // Fixed array length (as smi).
1020 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); 1013 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS);
1021 __ LoadSmiLiteral(r2, Smi::FromInt(0)); 1014 __ LoadSmiLiteral(r2, Smi::FromInt(0));
1022 __ Push(r2); // Initial index. 1015 __ Push(r2); // Initial index.
1023 1016
1024 // Generate code for doing the condition check. 1017 // Generate code for doing the condition check.
1025 __ bind(&loop); 1018 __ bind(&loop);
(...skipping 16 matching lines...) Expand all
1042 __ LoadP(r4, MemOperand(sp, 3 * kPointerSize)); 1035 __ LoadP(r4, MemOperand(sp, 3 * kPointerSize));
1043 1036
1044 // Check if the expected map still matches that of the enumerable. 1037 // Check if the expected map still matches that of the enumerable.
1045 // If not, we may have to filter the key. 1038 // If not, we may have to filter the key.
1046 Label update_each; 1039 Label update_each;
1047 __ LoadP(r3, MemOperand(sp, 4 * kPointerSize)); 1040 __ LoadP(r3, MemOperand(sp, 4 * kPointerSize));
1048 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset)); 1041 __ LoadP(r6, FieldMemOperand(r3, HeapObject::kMapOffset));
1049 __ CmpP(r6, r4); 1042 __ CmpP(r6, r4);
1050 __ beq(&update_each); 1043 __ beq(&update_each);
1051 1044
1052 // We might get here from TurboFan or Crankshaft when something in the 1045 // We need to filter the key, record slow-path here.
1053 // for-in loop body deopts and only now notice in fullcodegen, that we 1046 int const vector_index = SmiFromSlot(slot)->value();
1054 // can now longer use the enum cache, i.e. left fast mode. So better record
1055 // this information here, in case we later OSR back into this loop or
1056 // reoptimize the whole function w/o rerunning the loop with the slow
1057 // mode object in fullcodegen (which would result in a deopt loop).
1058 __ EmitLoadTypeFeedbackVector(r2); 1047 __ EmitLoadTypeFeedbackVector(r2);
1059 __ mov(r4, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1048 __ mov(r4, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1060 __ StoreP( 1049 __ StoreP(
1061 r4, FieldMemOperand(r2, FixedArray::OffsetOfElementAt(vector_index)), r0); 1050 r4, FieldMemOperand(r2, FixedArray::OffsetOfElementAt(vector_index)), r0);
1062 1051
1063 // Convert the entry to a string or (smi) 0 if it isn't a property 1052 // Convert the entry to a string or (smi) 0 if it isn't a property
1064 // any more. If the property has been removed while iterating, we 1053 // any more. If the property has been removed while iterating, we
1065 // just skip it. 1054 // just skip it.
1066 __ Push(r3, r5); // Enumerable and current entry. 1055 __ Push(r3, r5); // Enumerable and current entry.
1067 __ CallRuntime(Runtime::kForInFilter); 1056 __ CallRuntime(Runtime::kForInFilter);
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 } 1752 }
1764 1753
1765 void FullCodeGenerator::VisitYield(Yield* expr) { 1754 void FullCodeGenerator::VisitYield(Yield* expr) {
1766 Comment cmnt(masm_, "[ Yield"); 1755 Comment cmnt(masm_, "[ Yield");
1767 SetExpressionPosition(expr); 1756 SetExpressionPosition(expr);
1768 1757
1769 // Evaluate yielded value first; the initial iterator definition depends on 1758 // Evaluate yielded value first; the initial iterator definition depends on
1770 // this. It stays on the stack while we update the iterator. 1759 // this. It stays on the stack while we update the iterator.
1771 VisitForStackValue(expr->expression()); 1760 VisitForStackValue(expr->expression());
1772 1761
1773 switch (expr->yield_kind()) { 1762 Label suspend, continuation, post_runtime, resume;
1774 case Yield::kSuspend:
1775 // Pop value from top-of-stack slot; box result into result register.
1776 EmitCreateIteratorResult(false);
1777 PushOperand(result_register());
1778 // Fall through.
1779 case Yield::kInitial: {
1780 Label suspend, continuation, post_runtime, resume;
1781 1763
1782 __ b(&suspend, Label::kNear); 1764 __ b(&suspend);
1783 __ bind(&continuation); 1765 __ bind(&continuation);
1784 // When we arrive here, the stack top is the resume mode and 1766 // When we arrive here, the stack top is the resume mode and
1785 // result_register() holds the input value (the argument given to the 1767 // result_register() holds the input value (the argument given to the
1786 // respective resume operation). 1768 // respective resume operation).
1787 __ RecordGeneratorContinuation(); 1769 __ RecordGeneratorContinuation();
1788 __ pop(r3); 1770 __ pop(r3);
1789 __ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::RETURN), r0); 1771 __ CmpSmiLiteral(r3, Smi::FromInt(JSGeneratorObject::RETURN), r0);
1790 __ bne(&resume); 1772 __ bne(&resume);
1791 __ push(result_register()); 1773 __ push(result_register());
1792 EmitCreateIteratorResult(true); 1774 EmitCreateIteratorResult(true);
1793 EmitUnwindAndReturn(); 1775 EmitUnwindAndReturn();
1794 1776
1795 __ bind(&suspend); 1777 __ bind(&suspend);
1796 OperandStackDepthIncrement(1); // Not popped on this path. 1778 OperandStackDepthIncrement(1); // Not popped on this path.
1797 VisitForAccumulatorValue(expr->generator_object()); 1779 VisitForAccumulatorValue(expr->generator_object());
1798 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1780 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1799 __ LoadSmiLiteral(r3, Smi::FromInt(continuation.pos())); 1781 __ LoadSmiLiteral(r3, Smi::FromInt(continuation.pos()));
1800 __ StoreP(r3, 1782 __ StoreP(r3, FieldMemOperand(r2, JSGeneratorObject::kContinuationOffset),
1801 FieldMemOperand(r2, JSGeneratorObject::kContinuationOffset)); 1783 r0);
1802 __ StoreP(cp, FieldMemOperand(r2, JSGeneratorObject::kContextOffset)); 1784 __ StoreP(cp, FieldMemOperand(r2, JSGeneratorObject::kContextOffset), r0);
1803 __ LoadRR(r3, cp); 1785 __ LoadRR(r3, cp);
1804 __ RecordWriteField(r2, JSGeneratorObject::kContextOffset, r3, r4, 1786 __ RecordWriteField(r2, JSGeneratorObject::kContextOffset, r3, r4,
1805 kLRHasBeenSaved, kDontSaveFPRegs); 1787 kLRHasBeenSaved, kDontSaveFPRegs);
1806 __ AddP(r3, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1788 __ AddP(r3, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1807 __ CmpP(sp, r3); 1789 __ CmpP(sp, r3);
1808 __ beq(&post_runtime); 1790 __ beq(&post_runtime);
1809 __ push(r2); // generator object 1791 __ push(r2); // generator object
1810 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1792 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1811 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1793 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1812 __ bind(&post_runtime); 1794 __ bind(&post_runtime);
1813 PopOperand(result_register()); 1795 PopOperand(result_register());
1814 EmitReturnSequence(); 1796 EmitReturnSequence();
1815 1797
1816 __ bind(&resume); 1798 __ bind(&resume);
1817 context()->Plug(result_register()); 1799 context()->Plug(result_register());
1818 break;
1819 }
1820
1821 case Yield::kFinal: {
1822 // Pop value from top-of-stack slot, box result into result register.
1823 EmitCreateIteratorResult(true);
1824 EmitUnwindAndReturn();
1825 break;
1826 }
1827
1828 case Yield::kDelegating:
1829 UNREACHABLE();
1830 }
1831 } 1800 }
1832 1801
1833 void FullCodeGenerator::EmitGeneratorResume( 1802 void FullCodeGenerator::EmitGeneratorResume(
1834 Expression* generator, Expression* value, 1803 Expression* generator, Expression* value,
1835 JSGeneratorObject::ResumeMode resume_mode) { 1804 JSGeneratorObject::ResumeMode resume_mode) {
1836 // The value stays in r2, and is ultimately read by the resumed generator, as 1805 // The value stays in r2, and is ultimately read by the resumed generator, as
1837 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 1806 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1838 // is read to throw the value when the resumed generator is already closed. 1807 // is read to throw the value when the resumed generator is already closed.
1839 // r3 will hold the generator object until the activation has been resumed. 1808 // r3 will hold the generator object until the activation has been resumed.
1840 VisitForStackValue(generator); 1809 VisitForStackValue(generator);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 // the generator was suspended. 1848 // the generator was suspended.
1880 Label resume_frame, done; 1849 Label resume_frame, done;
1881 __ bind(&push_frame); 1850 __ bind(&push_frame);
1882 __ b(r14, &resume_frame); // brasl 1851 __ b(r14, &resume_frame); // brasl
1883 __ b(&done); 1852 __ b(&done);
1884 __ bind(&resume_frame); 1853 __ bind(&resume_frame);
1885 // lr = return address. 1854 // lr = return address.
1886 // fp = caller's frame pointer. 1855 // fp = caller's frame pointer.
1887 // cp = callee's context, 1856 // cp = callee's context,
1888 // r6 = callee's JS function. 1857 // r6 = callee's JS function.
1889 __ PushFixedFrame(r6); 1858 __ PushStandardFrame(r6);
1890 // Adjust FP to point to saved FP.
1891 __ lay(fp, MemOperand(sp, StandardFrameConstants::kFixedFrameSizeFromFp));
1892 1859
1893 // Load the operand stack size. 1860 // Load the operand stack size.
1894 __ LoadP(r5, FieldMemOperand(r3, JSGeneratorObject::kOperandStackOffset)); 1861 __ LoadP(r5, FieldMemOperand(r3, JSGeneratorObject::kOperandStackOffset));
1895 __ LoadP(r5, FieldMemOperand(r5, FixedArray::kLengthOffset)); 1862 __ LoadP(r5, FieldMemOperand(r5, FixedArray::kLengthOffset));
1896 __ SmiUntag(r5); 1863 __ SmiUntag(r5);
1897 1864
1898 // If we are sending a value and there is no operand stack, we can jump back 1865 // If we are sending a value and there is no operand stack, we can jump back
1899 // in directly. 1866 // in directly.
1900 Label call_resume; 1867 Label call_resume;
1901 if (resume_mode == JSGeneratorObject::NEXT) { 1868 if (resume_mode == JSGeneratorObject::NEXT) {
(...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after
3877 3844
3878 VisitForAccumulatorValue(sub_expr); 3845 VisitForAccumulatorValue(sub_expr);
3879 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3846 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3880 if (expr->op() == Token::EQ_STRICT) { 3847 if (expr->op() == Token::EQ_STRICT) {
3881 Heap::RootListIndex nil_value = nil == kNullValue 3848 Heap::RootListIndex nil_value = nil == kNullValue
3882 ? Heap::kNullValueRootIndex 3849 ? Heap::kNullValueRootIndex
3883 : Heap::kUndefinedValueRootIndex; 3850 : Heap::kUndefinedValueRootIndex;
3884 __ CompareRoot(r2, nil_value); 3851 __ CompareRoot(r2, nil_value);
3885 Split(eq, if_true, if_false, fall_through); 3852 Split(eq, if_true, if_false, fall_through);
3886 } else { 3853 } else {
3887 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 3854 __ JumpIfSmi(r2, if_false);
3888 CallIC(ic, expr->CompareOperationFeedbackId()); 3855 __ LoadP(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
3889 __ CompareRoot(r2, Heap::kTrueValueRootIndex); 3856 __ LoadlB(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
3890 Split(eq, if_true, if_false, fall_through); 3857 __ AndP(r0, r3, Operand(1 << Map::kIsUndetectable));
3858 Split(ne, if_true, if_false, fall_through);
3891 } 3859 }
3892 context()->Plug(if_true, if_false); 3860 context()->Plug(if_true, if_false);
3893 } 3861 }
3894 3862
3895 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 3863 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
3896 __ LoadP(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3864 __ LoadP(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3897 context()->Plug(r2); 3865 context()->Plug(r2);
3898 } 3866 }
3899 3867
3900 Register FullCodeGenerator::result_register() { return r2; } 3868 Register FullCodeGenerator::result_register() { return r2; }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 3924
3957 void FullCodeGenerator::ClearPendingMessage() { 3925 void FullCodeGenerator::ClearPendingMessage() {
3958 DCHECK(!result_register().is(r3)); 3926 DCHECK(!result_register().is(r3));
3959 ExternalReference pending_message_obj = 3927 ExternalReference pending_message_obj =
3960 ExternalReference::address_of_pending_message_obj(isolate()); 3928 ExternalReference::address_of_pending_message_obj(isolate());
3961 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); 3929 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
3962 __ mov(ip, Operand(pending_message_obj)); 3930 __ mov(ip, Operand(pending_message_obj));
3963 __ StoreP(r3, MemOperand(ip)); 3931 __ StoreP(r3, MemOperand(ip));
3964 } 3932 }
3965 3933
3966 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) {
3967 DCHECK(!slot.IsInvalid());
3968 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(),
3969 Operand(SmiFromSlot(slot)));
3970 }
3971
3972 void FullCodeGenerator::DeferredCommands::EmitCommands() { 3934 void FullCodeGenerator::DeferredCommands::EmitCommands() {
3973 DCHECK(!result_register().is(r3)); 3935 DCHECK(!result_register().is(r3));
3974 // Restore the accumulator (r2) and token (r3). 3936 // Restore the accumulator (r2) and token (r3).
3975 __ Pop(r3, result_register()); 3937 __ Pop(r3, result_register());
3976 for (DeferredCommand cmd : commands_) { 3938 for (DeferredCommand cmd : commands_) {
3977 Label skip; 3939 Label skip;
3978 __ CmpSmiLiteral(r3, Smi::FromInt(cmd.token), r0); 3940 __ CmpSmiLiteral(r3, Smi::FromInt(cmd.token), r0);
3979 __ bne(&skip); 3941 __ bne(&skip);
3980 switch (cmd.command) { 3942 switch (cmd.command) {
3981 case kReturn: 3943 case kReturn:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4020 case INTERRUPT: { 3982 case INTERRUPT: {
4021 // <decrement profiling counter> 3983 // <decrement profiling counter>
4022 // bge <ok> ;; patched to GE BRC 3984 // bge <ok> ;; patched to GE BRC
4023 // brasrl r14, <interrupt stub address> 3985 // brasrl r14, <interrupt stub address>
4024 // <reset profiling counter> 3986 // <reset profiling counter>
4025 // ok-label 3987 // ok-label
4026 patcher.masm()->brc(ge, Operand(kBackEdgeBranchOffset)); 3988 patcher.masm()->brc(ge, Operand(kBackEdgeBranchOffset));
4027 break; 3989 break;
4028 } 3990 }
4029 case ON_STACK_REPLACEMENT: 3991 case ON_STACK_REPLACEMENT:
4030 case OSR_AFTER_STACK_CHECK:
4031 // <decrement profiling counter> 3992 // <decrement profiling counter>
4032 // brc 0x0, <ok> ;; patched to NOP BRC 3993 // brc 0x0, <ok> ;; patched to NOP BRC
4033 // brasrl r14, <interrupt stub address> 3994 // brasrl r14, <interrupt stub address>
4034 // <reset profiling counter> 3995 // <reset profiling counter>
4035 // ok-label ----- pc_after points here 3996 // ok-label ----- pc_after points here
4036 patcher.masm()->brc(CC_NOP, Operand(kBackEdgeBranchOffset)); 3997 patcher.masm()->brc(CC_NOP, Operand(kBackEdgeBranchOffset));
4037 break; 3998 break;
4038 } 3999 }
4039 4000
4040 // Replace the stack check address in the mov sequence with the 4001 // Replace the stack check address in the mov sequence with the
4041 // entry address of the replacement code. 4002 // entry address of the replacement code.
4042 Assembler::set_target_address_at(isolate, call_address, unoptimized_code, 4003 Assembler::set_target_address_at(isolate, call_address, unoptimized_code,
4043 replacement_code->entry()); 4004 replacement_code->entry());
4044 4005
4045 unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( 4006 unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch(
4046 unoptimized_code, call_address, replacement_code); 4007 unoptimized_code, call_address, replacement_code);
4047 } 4008 }
4048 4009
4049 BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( 4010 BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
4050 Isolate* isolate, Code* unoptimized_code, Address pc) { 4011 Isolate* isolate, Code* unoptimized_code, Address pc) {
4051 Address call_address = Assembler::target_address_from_return_address(pc); 4012 Address call_address = Assembler::target_address_from_return_address(pc);
4052 Address branch_address = call_address - 4; 4013 Address branch_address = call_address - 4;
4014 #ifdef DEBUG
4053 Address interrupt_address = 4015 Address interrupt_address =
4054 Assembler::target_address_at(call_address, unoptimized_code); 4016 Assembler::target_address_at(call_address, unoptimized_code);
4017 #endif
4055 4018
4056 DCHECK(BRC == Instruction::S390OpcodeValue(branch_address)); 4019 DCHECK(BRC == Instruction::S390OpcodeValue(branch_address));
4057 // For interrupt, we expect a branch greater than or equal 4020 // For interrupt, we expect a branch greater than or equal
4058 // i.e. BRC 0xa, +XXXX (0xA7A4XXXX) 4021 // i.e. BRC 0xa, +XXXX (0xA7A4XXXX)
4059 FourByteInstr br_instr = Instruction::InstructionBits( 4022 FourByteInstr br_instr = Instruction::InstructionBits(
4060 reinterpret_cast<const byte*>(branch_address)); 4023 reinterpret_cast<const byte*>(branch_address));
4061 if (kInterruptBranchInstruction == br_instr) { 4024 if (kInterruptBranchInstruction == br_instr) {
4062 DCHECK(interrupt_address == isolate->builtins()->InterruptCheck()->entry()); 4025 DCHECK(interrupt_address == isolate->builtins()->InterruptCheck()->entry());
4063 return INTERRUPT; 4026 return INTERRUPT;
4064 } 4027 }
4065 4028
4066 // Expect BRC to be patched to NOP branch. 4029 // Expect BRC to be patched to NOP branch.
4067 // i.e. BRC 0x0, +XXXX (0xA704XXXX) 4030 // i.e. BRC 0x0, +XXXX (0xA704XXXX)
4068 USE(kOSRBranchInstruction); 4031 USE(kOSRBranchInstruction);
4069 DCHECK(kOSRBranchInstruction == br_instr); 4032 DCHECK(kOSRBranchInstruction == br_instr);
4070 4033
4071 if (interrupt_address == isolate->builtins()->OnStackReplacement()->entry()) {
4072 return ON_STACK_REPLACEMENT;
4073 }
4074
4075 DCHECK(interrupt_address == 4034 DCHECK(interrupt_address ==
4076 isolate->builtins()->OsrAfterStackCheck()->entry()); 4035 isolate->builtins()->OnStackReplacement()->entry());
4077 return OSR_AFTER_STACK_CHECK; 4036 return ON_STACK_REPLACEMENT;
4078 } 4037 }
4079 4038
4080 } // namespace internal 4039 } // namespace internal
4081 } // namespace v8 4040 } // namespace v8
4082 #endif // V8_TARGET_ARCH_S390 4041 #endif // V8_TARGET_ARCH_S390
OLDNEW
« no previous file with comments | « src/debug/s390/debug-s390.cc ('k') | src/ic/s390/handler-compiler-s390.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698