| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 SmiCheck smi_check) { | 268 SmiCheck smi_check) { |
| 269 ASSERT(!AreAliased(object, address, value, t8)); | 269 ASSERT(!AreAliased(object, address, value, t8)); |
| 270 ASSERT(!AreAliased(object, address, value, t9)); | 270 ASSERT(!AreAliased(object, address, value, t9)); |
| 271 | 271 |
| 272 if (emit_debug_code()) { | 272 if (emit_debug_code()) { |
| 273 lw(at, MemOperand(address)); | 273 lw(at, MemOperand(address)); |
| 274 Assert( | 274 Assert( |
| 275 eq, kWrongAddressOrValuePassedToRecordWrite, at, Operand(value)); | 275 eq, kWrongAddressOrValuePassedToRecordWrite, at, Operand(value)); |
| 276 } | 276 } |
| 277 | 277 |
| 278 // Count number of write barriers in generated code. |
| 279 isolate()->counters()->write_barriers_static()->Increment(); |
| 280 // TODO(mstarzinger): Dynamic counter missing. |
| 281 |
| 282 // First, check if a write barrier is even needed. The tests below |
| 283 // catch stores of smis and stores into the young generation. |
| 278 Label done; | 284 Label done; |
| 279 | 285 |
| 280 if (smi_check == INLINE_SMI_CHECK) { | 286 if (smi_check == INLINE_SMI_CHECK) { |
| 281 ASSERT_EQ(0, kSmiTag); | 287 ASSERT_EQ(0, kSmiTag); |
| 282 JumpIfSmi(value, &done); | 288 JumpIfSmi(value, &done); |
| 283 } | 289 } |
| 284 | 290 |
| 285 CheckPageFlag(value, | 291 CheckPageFlag(value, |
| 286 value, // Used as scratch. | 292 value, // Used as scratch. |
| 287 MemoryChunk::kPointersToHereAreInterestingMask, | 293 MemoryChunk::kPointersToHereAreInterestingMask, |
| (...skipping 4221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4509 bind(&ok); | 4515 bind(&ok); |
| 4510 } | 4516 } |
| 4511 } | 4517 } |
| 4512 | 4518 |
| 4513 | 4519 |
| 4514 void MacroAssembler::Prologue(PrologueFrameMode frame_mode) { | 4520 void MacroAssembler::Prologue(PrologueFrameMode frame_mode) { |
| 4515 if (frame_mode == BUILD_STUB_FRAME) { | 4521 if (frame_mode == BUILD_STUB_FRAME) { |
| 4516 Push(ra, fp, cp); | 4522 Push(ra, fp, cp); |
| 4517 Push(Smi::FromInt(StackFrame::STUB)); | 4523 Push(Smi::FromInt(StackFrame::STUB)); |
| 4518 // Adjust FP to point to saved FP. | 4524 // Adjust FP to point to saved FP. |
| 4519 Addu(fp, sp, Operand(2 * kPointerSize)); | 4525 Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 4520 } else { | 4526 } else { |
| 4521 PredictableCodeSizeScope predictible_code_size_scope( | 4527 PredictableCodeSizeScope predictible_code_size_scope( |
| 4522 this, kNoCodeAgeSequenceLength * Assembler::kInstrSize); | 4528 this, kNoCodeAgeSequenceLength * Assembler::kInstrSize); |
| 4523 // The following three instructions must remain together and unmodified | 4529 // The following three instructions must remain together and unmodified |
| 4524 // for code aging to work properly. | 4530 // for code aging to work properly. |
| 4525 if (isolate()->IsCodePreAgingActive()) { | 4531 if (isolate()->IsCodePreAgingActive()) { |
| 4526 // Pre-age the code. | 4532 // Pre-age the code. |
| 4527 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); | 4533 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); |
| 4528 nop(Assembler::CODE_AGE_MARKER_NOP); | 4534 nop(Assembler::CODE_AGE_MARKER_NOP); |
| 4529 // Save the function's original return address | 4535 // Load the stub address to t9 and call it, |
| 4530 // (it will be clobbered by Call(t9)). | 4536 // GetCodeAgeAndParity() extracts the stub address from this instruction. |
| 4531 mov(at, ra); | |
| 4532 // Load the stub address to t9 and call it. | |
| 4533 li(t9, | 4537 li(t9, |
| 4534 Operand(reinterpret_cast<uint32_t>(stub->instruction_start()))); | 4538 Operand(reinterpret_cast<uint32_t>(stub->instruction_start())), |
| 4535 Call(t9); | 4539 CONSTANT_SIZE); |
| 4536 // Record the stub address in the empty space for GetCodeAgeAndParity(). | 4540 nop(); // Prevent jalr to jal optimization. |
| 4537 emit_code_stub_address(stub); | 4541 jalr(t9, a0); |
| 4542 nop(); // Branch delay slot nop. |
| 4543 nop(); // Pad the empty space. |
| 4538 } else { | 4544 } else { |
| 4539 Push(ra, fp, cp, a1); | 4545 Push(ra, fp, cp, a1); |
| 4540 nop(Assembler::CODE_AGE_SEQUENCE_NOP); | 4546 nop(Assembler::CODE_AGE_SEQUENCE_NOP); |
| 4541 // Adjust fp to point to caller's fp. | 4547 // Adjust fp to point to caller's fp. |
| 4542 Addu(fp, sp, Operand(2 * kPointerSize)); | 4548 Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 4543 } | 4549 } |
| 4544 } | 4550 } |
| 4545 } | 4551 } |
| 4546 | 4552 |
| 4547 | 4553 |
| 4548 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 4554 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
| 4549 addiu(sp, sp, -5 * kPointerSize); | 4555 addiu(sp, sp, -5 * kPointerSize); |
| 4550 li(t8, Operand(Smi::FromInt(type))); | 4556 li(t8, Operand(Smi::FromInt(type))); |
| 4551 li(t9, Operand(CodeObject()), CONSTANT_SIZE); | 4557 li(t9, Operand(CodeObject()), CONSTANT_SIZE); |
| 4552 sw(ra, MemOperand(sp, 4 * kPointerSize)); | 4558 sw(ra, MemOperand(sp, 4 * kPointerSize)); |
| 4553 sw(fp, MemOperand(sp, 3 * kPointerSize)); | 4559 sw(fp, MemOperand(sp, 3 * kPointerSize)); |
| 4554 sw(cp, MemOperand(sp, 2 * kPointerSize)); | 4560 sw(cp, MemOperand(sp, 2 * kPointerSize)); |
| 4555 sw(t8, MemOperand(sp, 1 * kPointerSize)); | 4561 sw(t8, MemOperand(sp, 1 * kPointerSize)); |
| 4556 sw(t9, MemOperand(sp, 0 * kPointerSize)); | 4562 sw(t9, MemOperand(sp, 0 * kPointerSize)); |
| 4557 addiu(fp, sp, 3 * kPointerSize); | 4563 // Adjust FP to point to saved FP. |
| 4564 Addu(fp, sp, |
| 4565 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); |
| 4558 } | 4566 } |
| 4559 | 4567 |
| 4560 | 4568 |
| 4561 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 4569 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
| 4562 mov(sp, fp); | 4570 mov(sp, fp); |
| 4563 lw(fp, MemOperand(sp, 0 * kPointerSize)); | 4571 lw(fp, MemOperand(sp, 0 * kPointerSize)); |
| 4564 lw(ra, MemOperand(sp, 1 * kPointerSize)); | 4572 lw(ra, MemOperand(sp, 1 * kPointerSize)); |
| 4565 addiu(sp, sp, 2 * kPointerSize); | 4573 addiu(sp, sp, 2 * kPointerSize); |
| 4566 } | 4574 } |
| 4567 | 4575 |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4836 STATIC_ASSERT(kSmiTag == 0); | 4844 STATIC_ASSERT(kSmiTag == 0); |
| 4837 andi(at, object, kSmiTagMask); | 4845 andi(at, object, kSmiTagMask); |
| 4838 Check(eq, kOperandIsASmi, at, Operand(zero_reg)); | 4846 Check(eq, kOperandIsASmi, at, Operand(zero_reg)); |
| 4839 } | 4847 } |
| 4840 } | 4848 } |
| 4841 | 4849 |
| 4842 | 4850 |
| 4843 void MacroAssembler::AssertString(Register object) { | 4851 void MacroAssembler::AssertString(Register object) { |
| 4844 if (emit_debug_code()) { | 4852 if (emit_debug_code()) { |
| 4845 STATIC_ASSERT(kSmiTag == 0); | 4853 STATIC_ASSERT(kSmiTag == 0); |
| 4846 And(t0, object, Operand(kSmiTagMask)); | 4854 SmiTst(object, t0); |
| 4847 Check(ne, kOperandIsASmiAndNotAString, t0, Operand(zero_reg)); | 4855 Check(ne, kOperandIsASmiAndNotAString, t0, Operand(zero_reg)); |
| 4848 push(object); | 4856 push(object); |
| 4849 lw(object, FieldMemOperand(object, HeapObject::kMapOffset)); | 4857 lw(object, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 4850 lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset)); | 4858 lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset)); |
| 4851 Check(lo, kOperandIsNotAString, object, Operand(FIRST_NONSTRING_TYPE)); | 4859 Check(lo, kOperandIsNotAString, object, Operand(FIRST_NONSTRING_TYPE)); |
| 4852 pop(object); | 4860 pop(object); |
| 4853 } | 4861 } |
| 4854 } | 4862 } |
| 4855 | 4863 |
| 4856 | 4864 |
| 4857 void MacroAssembler::AssertName(Register object) { | 4865 void MacroAssembler::AssertName(Register object) { |
| 4858 if (emit_debug_code()) { | 4866 if (emit_debug_code()) { |
| 4859 STATIC_ASSERT(kSmiTag == 0); | 4867 STATIC_ASSERT(kSmiTag == 0); |
| 4860 And(t0, object, Operand(kSmiTagMask)); | 4868 SmiTst(object, t0); |
| 4861 Check(ne, kOperandIsASmiAndNotAName, t0, Operand(zero_reg)); | 4869 Check(ne, kOperandIsASmiAndNotAName, t0, Operand(zero_reg)); |
| 4862 push(object); | 4870 push(object); |
| 4863 lw(object, FieldMemOperand(object, HeapObject::kMapOffset)); | 4871 lw(object, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 4864 lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset)); | 4872 lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset)); |
| 4865 Check(le, kOperandIsNotAName, object, Operand(LAST_NAME_TYPE)); | 4873 Check(le, kOperandIsNotAName, object, Operand(LAST_NAME_TYPE)); |
| 4866 pop(object); | 4874 pop(object); |
| 4867 } | 4875 } |
| 4868 } | 4876 } |
| 4869 | 4877 |
| 4870 | 4878 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5050 return stack_passed_words; | 5058 return stack_passed_words; |
| 5051 } | 5059 } |
| 5052 | 5060 |
| 5053 | 5061 |
| 5054 void MacroAssembler::EmitSeqStringSetCharCheck(Register string, | 5062 void MacroAssembler::EmitSeqStringSetCharCheck(Register string, |
| 5055 Register index, | 5063 Register index, |
| 5056 Register value, | 5064 Register value, |
| 5057 Register scratch, | 5065 Register scratch, |
| 5058 uint32_t encoding_mask) { | 5066 uint32_t encoding_mask) { |
| 5059 Label is_object; | 5067 Label is_object; |
| 5060 And(at, string, Operand(kSmiTagMask)); | 5068 SmiTst(string, at); |
| 5061 ThrowIf(eq, kNonObject, at, Operand(zero_reg)); | 5069 ThrowIf(eq, kNonObject, at, Operand(zero_reg)); |
| 5062 | 5070 |
| 5063 lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); | 5071 lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); |
| 5064 lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); | 5072 lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); |
| 5065 | 5073 |
| 5066 andi(at, at, kStringRepresentationMask | kStringEncodingMask); | 5074 andi(at, at, kStringRepresentationMask | kStringEncodingMask); |
| 5067 li(scratch, Operand(encoding_mask)); | 5075 li(scratch, Operand(encoding_mask)); |
| 5068 ThrowIf(ne, kUnexpectedStringType, at, Operand(scratch)); | 5076 ThrowIf(ne, kUnexpectedStringType, at, Operand(scratch)); |
| 5069 | 5077 |
| 5070 // The index is assumed to be untagged coming in, tag it to compare with the | 5078 // The index is assumed to be untagged coming in, tag it to compare with the |
| 5071 // string length without using a temp register, it is restored at the end of | 5079 // string length without using a temp register, it is restored at the end of |
| 5072 // this function. | 5080 // this function. |
| 5073 Label index_tag_ok, index_tag_bad; | 5081 Label index_tag_ok, index_tag_bad; |
| 5074 // On ARM TrySmiTag is used here. | 5082 TrySmiTag(index, scratch, &index_tag_bad); |
| 5075 AdduAndCheckForOverflow(index, index, index, scratch); | |
| 5076 BranchOnOverflow(&index_tag_bad, scratch); | |
| 5077 Branch(&index_tag_ok); | 5083 Branch(&index_tag_ok); |
| 5078 bind(&index_tag_bad); | 5084 bind(&index_tag_bad); |
| 5079 Throw(kIndexIsTooLarge); | 5085 Throw(kIndexIsTooLarge); |
| 5080 bind(&index_tag_ok); | 5086 bind(&index_tag_ok); |
| 5081 | 5087 |
| 5082 lw(at, FieldMemOperand(string, String::kLengthOffset)); | 5088 lw(at, FieldMemOperand(string, String::kLengthOffset)); |
| 5083 ThrowIf(ge, kIndexIsTooLarge, index, Operand(at)); | 5089 ThrowIf(ge, kIndexIsTooLarge, index, Operand(at)); |
| 5084 | 5090 |
| 5085 li(at, Operand(Smi::FromInt(0))); | 5091 ASSERT(Smi::FromInt(0) == 0); |
| 5086 ThrowIf(lt, kIndexIsNegative, index, Operand(at)); | 5092 ThrowIf(lt, kIndexIsNegative, index, Operand(zero_reg)); |
| 5087 | 5093 |
| 5088 SmiUntag(index, index); | 5094 SmiUntag(index, index); |
| 5089 } | 5095 } |
| 5090 | 5096 |
| 5091 | 5097 |
| 5092 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments, | 5098 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments, |
| 5093 int num_double_arguments, | 5099 int num_double_arguments, |
| 5094 Register scratch) { | 5100 Register scratch) { |
| 5095 int frame_alignment = ActivationFrameAlignment(); | 5101 int frame_alignment = ActivationFrameAlignment(); |
| 5096 | 5102 |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5749 opcode == BGTZL); | 5755 opcode == BGTZL); |
| 5750 opcode = (cond == eq) ? BEQ : BNE; | 5756 opcode = (cond == eq) ? BEQ : BNE; |
| 5751 instr = (instr & ~kOpcodeMask) | opcode; | 5757 instr = (instr & ~kOpcodeMask) | opcode; |
| 5752 masm_.emit(instr); | 5758 masm_.emit(instr); |
| 5753 } | 5759 } |
| 5754 | 5760 |
| 5755 | 5761 |
| 5756 } } // namespace v8::internal | 5762 } } // namespace v8::internal |
| 5757 | 5763 |
| 5758 #endif // V8_TARGET_ARCH_MIPS | 5764 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |