| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 #include "src/compiler/code-generator.h" | 6 #include "src/compiler/code-generator.h" |
| 7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
| 8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 public: | 217 public: |
| 218 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, | 218 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, |
| 219 Register value, Register scratch0, Register scratch1, | 219 Register value, Register scratch0, Register scratch1, |
| 220 RecordWriteMode mode) | 220 RecordWriteMode mode) |
| 221 : OutOfLineCode(gen), | 221 : OutOfLineCode(gen), |
| 222 object_(object), | 222 object_(object), |
| 223 index_(index), | 223 index_(index), |
| 224 value_(value), | 224 value_(value), |
| 225 scratch0_(scratch0), | 225 scratch0_(scratch0), |
| 226 scratch1_(scratch1), | 226 scratch1_(scratch1), |
| 227 mode_(mode) {} | 227 mode_(mode), |
| 228 must_save_lr_(gen->frame_access_state()->has_frame()) {} |
| 228 | 229 |
| 229 void Generate() final { | 230 void Generate() final { |
| 230 if (mode_ > RecordWriteMode::kValueIsPointer) { | 231 if (mode_ > RecordWriteMode::kValueIsPointer) { |
| 231 __ JumpIfSmi(value_, exit()); | 232 __ JumpIfSmi(value_, exit()); |
| 232 } | 233 } |
| 233 __ CheckPageFlag(value_, scratch0_, | 234 __ CheckPageFlag(value_, scratch0_, |
| 234 MemoryChunk::kPointersToHereAreInterestingMask, eq, | 235 MemoryChunk::kPointersToHereAreInterestingMask, eq, |
| 235 exit()); | 236 exit()); |
| 236 RememberedSetAction const remembered_set_action = | 237 RememberedSetAction const remembered_set_action = |
| 237 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET | 238 mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET |
| 238 : OMIT_REMEMBERED_SET; | 239 : OMIT_REMEMBERED_SET; |
| 239 SaveFPRegsMode const save_fp_mode = | 240 SaveFPRegsMode const save_fp_mode = |
| 240 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; | 241 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
| 241 if (!frame()->needs_frame()) { | 242 if (must_save_lr_) { |
| 242 // We need to save and restore ra if the frame was elided. | 243 // We need to save and restore ra if the frame was elided. |
| 243 __ Push(ra); | 244 __ Push(ra); |
| 244 } | 245 } |
| 245 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, | 246 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, |
| 246 remembered_set_action, save_fp_mode); | 247 remembered_set_action, save_fp_mode); |
| 247 __ Daddu(scratch1_, object_, index_); | 248 __ Daddu(scratch1_, object_, index_); |
| 248 __ CallStub(&stub); | 249 __ CallStub(&stub); |
| 249 if (!frame()->needs_frame()) { | 250 if (must_save_lr_) { |
| 250 __ Pop(ra); | 251 __ Pop(ra); |
| 251 } | 252 } |
| 252 } | 253 } |
| 253 | 254 |
| 254 private: | 255 private: |
| 255 Register const object_; | 256 Register const object_; |
| 256 Register const index_; | 257 Register const index_; |
| 257 Register const value_; | 258 Register const value_; |
| 258 Register const scratch0_; | 259 Register const scratch0_; |
| 259 Register const scratch1_; | 260 Register const scratch1_; |
| 260 RecordWriteMode const mode_; | 261 RecordWriteMode const mode_; |
| 262 bool must_save_lr_; |
| 261 }; | 263 }; |
| 262 | 264 |
| 263 | 265 |
| 264 Condition FlagsConditionToConditionCmp(FlagsCondition condition) { | 266 Condition FlagsConditionToConditionCmp(FlagsCondition condition) { |
| 265 switch (condition) { | 267 switch (condition) { |
| 266 case kEqual: | 268 case kEqual: |
| 267 return eq; | 269 return eq; |
| 268 case kNotEqual: | 270 case kNotEqual: |
| 269 return ne; | 271 return ne; |
| 270 case kSignedLessThan: | 272 case kSignedLessThan: |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \ | 477 Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \ |
| 476 __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 478 __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 477 __ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 479 __ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 478 __ mfc1(at, i.OutputDoubleRegister()); \ | 480 __ mfc1(at, i.OutputDoubleRegister()); \ |
| 479 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ | 481 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ |
| 480 __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ | 482 __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ |
| 481 __ bind(ool->exit()); \ | 483 __ bind(ool->exit()); \ |
| 482 __ bind(&done); \ | 484 __ bind(&done); \ |
| 483 } | 485 } |
| 484 | 486 |
| 487 void CodeGenerator::AssembleDeconstructFrame() { |
| 488 __ mov(sp, fp); |
| 489 __ Pop(ra, fp); |
| 490 } |
| 491 |
| 492 void CodeGenerator::AssembleSetupStackPointer() {} |
| 493 |
| 485 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 494 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 486 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 495 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 487 if (sp_slot_delta > 0) { | 496 if (sp_slot_delta > 0) { |
| 488 __ daddiu(sp, sp, sp_slot_delta * kPointerSize); | 497 __ daddiu(sp, sp, sp_slot_delta * kPointerSize); |
| 489 } | 498 } |
| 490 frame_access_state()->SetFrameAccessToDefault(); | 499 frame_access_state()->SetFrameAccessToDefault(); |
| 491 } | 500 } |
| 492 | 501 |
| 493 | 502 |
| 494 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 503 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
| 495 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 504 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 496 if (sp_slot_delta < 0) { | 505 if (sp_slot_delta < 0) { |
| 497 __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize)); | 506 __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize)); |
| 498 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); | 507 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); |
| 499 } | 508 } |
| 500 if (frame()->needs_frame()) { | 509 if (frame_access_state()->has_frame()) { |
| 501 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 510 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
| 502 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 511 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 503 } | 512 } |
| 504 frame_access_state()->SetFrameAccessToSP(); | 513 frame_access_state()->SetFrameAccessToSP(); |
| 505 } | 514 } |
| 506 | 515 |
| 507 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, | 516 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, |
| 508 Register scratch1, | 517 Register scratch1, |
| 509 Register scratch2, | 518 Register scratch2, |
| 510 Register scratch3) { | 519 Register scratch3) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 case kArchRet: | 657 case kArchRet: |
| 649 AssembleReturn(); | 658 AssembleReturn(); |
| 650 break; | 659 break; |
| 651 case kArchStackPointer: | 660 case kArchStackPointer: |
| 652 __ mov(i.OutputRegister(), sp); | 661 __ mov(i.OutputRegister(), sp); |
| 653 break; | 662 break; |
| 654 case kArchFramePointer: | 663 case kArchFramePointer: |
| 655 __ mov(i.OutputRegister(), fp); | 664 __ mov(i.OutputRegister(), fp); |
| 656 break; | 665 break; |
| 657 case kArchParentFramePointer: | 666 case kArchParentFramePointer: |
| 658 if (frame_access_state()->frame()->needs_frame()) { | 667 if (frame_access_state()->has_frame()) { |
| 659 __ ld(i.OutputRegister(), MemOperand(fp, 0)); | 668 __ ld(i.OutputRegister(), MemOperand(fp, 0)); |
| 660 } else { | 669 } else { |
| 661 __ mov(i.OutputRegister(), fp); | 670 __ mov(i.OutputRegister(), fp); |
| 662 } | 671 } |
| 663 break; | 672 break; |
| 664 case kArchTruncateDoubleToI: | 673 case kArchTruncateDoubleToI: |
| 665 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); | 674 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); |
| 666 break; | 675 break; |
| 667 case kArchStoreWithWriteBarrier: { | 676 case kArchStoreWithWriteBarrier: { |
| 668 RecordWriteMode mode = | 677 RecordWriteMode mode = |
| (...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 void CodeGenerator::AssembleDeoptimizerCall( | 1872 void CodeGenerator::AssembleDeoptimizerCall( |
| 1864 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1873 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
| 1865 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1874 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
| 1866 isolate(), deoptimization_id, bailout_type); | 1875 isolate(), deoptimization_id, bailout_type); |
| 1867 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1876 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
| 1868 } | 1877 } |
| 1869 | 1878 |
| 1870 | 1879 |
| 1871 void CodeGenerator::AssemblePrologue() { | 1880 void CodeGenerator::AssemblePrologue() { |
| 1872 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1881 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1873 if (frame()->needs_frame()) { | 1882 if (frame_access_state()->has_frame()) { |
| 1874 if (descriptor->IsCFunctionCall()) { | 1883 if (descriptor->IsCFunctionCall()) { |
| 1875 __ Push(ra, fp); | 1884 __ Push(ra, fp); |
| 1876 __ mov(fp, sp); | 1885 __ mov(fp, sp); |
| 1877 } else if (descriptor->IsJSFunctionCall()) { | 1886 } else if (descriptor->IsJSFunctionCall()) { |
| 1878 __ Prologue(this->info()->GeneratePreagedPrologue()); | 1887 __ Prologue(this->info()->GeneratePreagedPrologue()); |
| 1879 } else { | 1888 } else { |
| 1880 __ StubPrologue(info()->GetOutputStackFrameType()); | 1889 __ StubPrologue(info()->GetOutputStackFrameType()); |
| 1881 } | 1890 } |
| 1882 } else { | |
| 1883 frame()->SetElidedFrameSizeInSlots(0); | |
| 1884 } | 1891 } |
| 1885 frame_access_state()->SetFrameAccessToDefault(); | |
| 1886 | 1892 |
| 1887 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 1893 int stack_shrink_slots = frame()->GetSpillSlotCount(); |
| 1888 if (info()->is_osr()) { | 1894 if (info()->is_osr()) { |
| 1889 // TurboFan OSR-compiled functions cannot be entered directly. | 1895 // TurboFan OSR-compiled functions cannot be entered directly. |
| 1890 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1896 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
| 1891 | 1897 |
| 1892 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1898 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
| 1893 // frame is still on the stack. Optimized code uses OSR values directly from | 1899 // frame is still on the stack. Optimized code uses OSR values directly from |
| 1894 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1900 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
| 1895 // remaining stack slots. | 1901 // remaining stack slots. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1934 __ MultiPop(saves); | 1940 __ MultiPop(saves); |
| 1935 } | 1941 } |
| 1936 | 1942 |
| 1937 // Restore FPU registers. | 1943 // Restore FPU registers. |
| 1938 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters(); | 1944 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters(); |
| 1939 if (saves_fpu != 0) { | 1945 if (saves_fpu != 0) { |
| 1940 __ MultiPopFPU(saves_fpu); | 1946 __ MultiPopFPU(saves_fpu); |
| 1941 } | 1947 } |
| 1942 | 1948 |
| 1943 if (descriptor->IsCFunctionCall()) { | 1949 if (descriptor->IsCFunctionCall()) { |
| 1944 __ mov(sp, fp); | 1950 AssembleDeconstructFrame(); |
| 1945 __ Pop(ra, fp); | 1951 } else if (frame_access_state()->has_frame()) { |
| 1946 } else if (frame()->needs_frame()) { | |
| 1947 // Canonicalize JSFunction return sites for now. | 1952 // Canonicalize JSFunction return sites for now. |
| 1948 if (return_label_.is_bound()) { | 1953 if (return_label_.is_bound()) { |
| 1949 __ Branch(&return_label_); | 1954 __ Branch(&return_label_); |
| 1950 return; | 1955 return; |
| 1951 } else { | 1956 } else { |
| 1952 __ bind(&return_label_); | 1957 __ bind(&return_label_); |
| 1953 __ mov(sp, fp); | 1958 AssembleDeconstructFrame(); |
| 1954 __ Pop(ra, fp); | |
| 1955 } | 1959 } |
| 1956 } | 1960 } |
| 1957 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1961 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
| 1958 if (pop_count != 0) { | 1962 if (pop_count != 0) { |
| 1959 __ DropAndRet(pop_count); | 1963 __ DropAndRet(pop_count); |
| 1960 } else { | 1964 } else { |
| 1961 __ Ret(); | 1965 __ Ret(); |
| 1962 } | 1966 } |
| 1963 } | 1967 } |
| 1964 | 1968 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2169 padding_size -= v8::internal::Assembler::kInstrSize; | 2173 padding_size -= v8::internal::Assembler::kInstrSize; |
| 2170 } | 2174 } |
| 2171 } | 2175 } |
| 2172 } | 2176 } |
| 2173 | 2177 |
| 2174 #undef __ | 2178 #undef __ |
| 2175 | 2179 |
| 2176 } // namespace compiler | 2180 } // namespace compiler |
| 2177 } // namespace internal | 2181 } // namespace internal |
| 2178 } // namespace v8 | 2182 } // namespace v8 |
| OLD | NEW |