Chromium Code Reviews| Index: src/arm/macro-assembler-arm.cc |
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
| index 90601952299e31a4210e2b9dccbbb489991a45c8..7d77588aee84d1ac518cb54af130c9ecda721b7a 100644 |
| --- a/src/arm/macro-assembler-arm.cc |
| +++ b/src/arm/macro-assembler-arm.cc |
| @@ -3391,6 +3391,38 @@ int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments, |
| } |
| +void MacroAssembler::EmitSeqStringSetCharCheck(Register string, |
| + Register index, |
| + Register value, |
| + uint32_t encoding_mask) { |
| + SmiTst(index); |
| + ThrowIfNot(eq, kNonSmiIndex); |
| + SmiTst(value); |
| + ThrowIfNot(eq, kNonSmiValue); |
| + |
| + Label is_object; |
| + tst(string, Operand(kSmiTagMask)); |
| + b(ne, &is_object); |
|
Yang
2013/11/19 14:35:29
Use ThrowIfNot(ne, kNonObject) instead?
Personall
danno
2013/11/19 16:19:14
Done.
|
| + Throw(kNonObject); |
| + bind(&is_object); |
| + |
| + |
| + ldr(ip, FieldMemOperand(string, String::kLengthOffset)); |
| + cmp(index, ip); |
| + ThrowIfNot(lt, kIndexIsTooLarge); |
| + |
| + cmp(index, Operand(Smi::FromInt(0))); |
| + ThrowIfNot(ge, kIndexIsNegative); |
| + |
| + ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset)); |
| + ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset)); |
| + |
| + and_(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask)); |
| + cmp(ip, Operand(encoding_mask)); |
| + ThrowIfNot(eq, kUnexpectedStringType); |
| +} |
| + |
| + |
| void MacroAssembler::PrepareCallCFunction(int num_reg_arguments, |
| int num_double_arguments, |
| Register scratch) { |
| @@ -3774,6 +3806,62 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg, |
| } |
| +void MacroAssembler::Throw(BailoutReason reason) { |
| + Label abort_start; |
| + bind(&abort_start); |
| + // We want to pass the msg string like a smi to avoid GC |
| + // problems, however msg is not guaranteed to be aligned |
| + // properly. Instead, we pass an aligned pointer that is |
| + // a proper v8 smi, but also pass the alignment difference |
| + // from the real pointer as a smi. |
| + const char* msg = GetBailoutReason(reason); |
| + intptr_t p1 = reinterpret_cast<intptr_t>(msg); |
| + intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; |
|
Yang
2013/11/19 14:35:29
How about just encoding the reason enum as smi and
danno
2013/11/19 16:19:14
Done.
|
| + ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); |
| +#ifdef DEBUG |
| + if (msg != NULL) { |
| + RecordComment("Throw message: "); |
| + RecordComment(msg); |
| + } |
| +#endif |
| + |
| + mov(r0, Operand(p0)); |
| + push(r0); |
| + mov(r0, Operand(Smi::FromInt(p1 - p0))); |
| + push(r0); |
| + // Disable stub call restrictions to always allow calls to throw. |
| + if (!has_frame_) { |
| + // We don't actually want to generate a pile of code for this, so just |
| + // claim there is a stack frame, without generating one. |
| + FrameScope scope(this, StackFrame::NONE); |
| + CallRuntime(Runtime::kThrowMessage, 2); |
| + } else { |
| + CallRuntime(Runtime::kThrowMessage, 2); |
| + } |
| + // will not return here |
| + if (is_const_pool_blocked()) { |
| + // If the calling code cares about the exact number of |
| + // instructions generated, we insert padding here to keep the size |
| + // of the Abort macro constant. |
| + static const int kExpectedAbortInstructions = 10; |
| + int abort_instructions = InstructionsGeneratedSince(&abort_start); |
| + ASSERT(abort_instructions <= kExpectedAbortInstructions); |
| + while (abort_instructions++ < kExpectedAbortInstructions) { |
| + nop(); |
| + } |
| + } |
| +} |
| + |
| + |
| +void MacroAssembler::ThrowIfNot(Condition cc, BailoutReason reason) { |
| + Label L; |
| + b(cc, &L); |
| + Throw(reason); |
| + // will not return here |
| + bind(&L); |
| +} |
| + |
| + |
| void MacroAssembler::LoadInstanceDescriptors(Register map, |
| Register descriptors) { |
| ldr(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset)); |