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 3925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3936 | 3936 |
3937 // Check if we should retry or throw exception. | 3937 // Check if we should retry or throw exception. |
3938 Label retry; | 3938 Label retry; |
3939 __ bind(&failure_returned); | 3939 __ bind(&failure_returned); |
3940 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0); | 3940 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0); |
3941 __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize); | 3941 __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize); |
3942 __ Branch(&retry, eq, t0, Operand(zero_reg)); | 3942 __ Branch(&retry, eq, t0, Operand(zero_reg)); |
3943 | 3943 |
3944 // Special handling of out of memory exceptions. | 3944 // Special handling of out of memory exceptions. |
3945 Failure* out_of_memory = Failure::OutOfMemoryException(); | 3945 Failure* out_of_memory = Failure::OutOfMemoryException(); |
3946 __ Branch(throw_out_of_memory_exception, eq, | 3946 __ Branch(throw_out_of_memory_exception, |
3947 v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 3947 eq, |
| 3948 v0, |
| 3949 Operand(reinterpret_cast<int32_t>(out_of_memory))); |
3948 | 3950 |
3949 // Retrieve the pending exception and clear the variable. | 3951 // Retrieve the pending exception and clear the variable. |
3950 __ li(a3, Operand(isolate->factory()->the_hole_value())); | 3952 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); |
3951 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 3953 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
3952 isolate))); | 3954 isolate))); |
3953 __ lw(v0, MemOperand(t0)); | 3955 __ lw(v0, MemOperand(t0)); |
3954 __ sw(a3, MemOperand(t0)); | 3956 __ sw(a3, MemOperand(t0)); |
3955 | 3957 |
3956 // Special handling of termination exceptions which are uncatchable | 3958 // Special handling of termination exceptions which are uncatchable |
3957 // by javascript code. | 3959 // by javascript code. |
3958 __ Branch(throw_termination_exception, eq, | 3960 __ LoadRoot(t0, Heap::kTerminationExceptionRootIndex); |
3959 v0, Operand(isolate->factory()->termination_exception())); | 3961 __ Branch(throw_termination_exception, eq, v0, Operand(t0)); |
3960 | 3962 |
3961 // Handle normal exception. | 3963 // Handle normal exception. |
3962 __ jmp(throw_normal_exception); | 3964 __ jmp(throw_normal_exception); |
3963 | 3965 |
3964 __ bind(&retry); | 3966 __ bind(&retry); |
3965 // Last failure (v0) will be moved to (a0) for parameter when retrying. | 3967 // Last failure (v0) will be moved to (a0) for parameter when retrying. |
3966 } | 3968 } |
3967 | 3969 |
3968 | 3970 |
3969 void CEntryStub::Generate(MacroAssembler* masm) { | 3971 void CEntryStub::Generate(MacroAssembler* masm) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4076 __ Move(kDoubleRegZero, 0.0); | 4078 __ Move(kDoubleRegZero, 0.0); |
4077 } | 4079 } |
4078 | 4080 |
4079 | 4081 |
4080 // Load argv in s0 register. | 4082 // Load argv in s0 register. |
4081 int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize; | 4083 int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize; |
4082 if (CpuFeatures::IsSupported(FPU)) { | 4084 if (CpuFeatures::IsSupported(FPU)) { |
4083 offset_to_argv += kNumCalleeSavedFPU * kDoubleSize; | 4085 offset_to_argv += kNumCalleeSavedFPU * kDoubleSize; |
4084 } | 4086 } |
4085 | 4087 |
| 4088 __ InitializeRootRegister(); |
4086 __ lw(s0, MemOperand(sp, offset_to_argv + kCArgsSlotsSize)); | 4089 __ lw(s0, MemOperand(sp, offset_to_argv + kCArgsSlotsSize)); |
4087 | 4090 |
4088 // We build an EntryFrame. | 4091 // We build an EntryFrame. |
4089 __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used. | 4092 __ li(t3, Operand(-1)); // Push a bad frame pointer to fail if it is used. |
4090 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 4093 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
4091 __ li(t2, Operand(Smi::FromInt(marker))); | 4094 __ li(t2, Operand(Smi::FromInt(marker))); |
4092 __ li(t1, Operand(Smi::FromInt(marker))); | 4095 __ li(t1, Operand(Smi::FromInt(marker))); |
4093 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, | 4096 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
4094 isolate))); | 4097 isolate))); |
4095 __ lw(t0, MemOperand(t0)); | 4098 __ lw(t0, MemOperand(t0)); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 // Invoke: Link this frame into the handler chain. There's only one | 4151 // Invoke: Link this frame into the handler chain. There's only one |
4149 // handler block in this code object, so its index is 0. | 4152 // handler block in this code object, so its index is 0. |
4150 __ bind(&invoke); | 4153 __ bind(&invoke); |
4151 __ PushTryHandler(StackHandler::JS_ENTRY, 0); | 4154 __ PushTryHandler(StackHandler::JS_ENTRY, 0); |
4152 // If an exception not caught by another handler occurs, this handler | 4155 // If an exception not caught by another handler occurs, this handler |
4153 // returns control to the code after the bal(&invoke) above, which | 4156 // returns control to the code after the bal(&invoke) above, which |
4154 // restores all kCalleeSaved registers (including cp and fp) to their | 4157 // restores all kCalleeSaved registers (including cp and fp) to their |
4155 // saved values before returning a failure to C. | 4158 // saved values before returning a failure to C. |
4156 | 4159 |
4157 // Clear any pending exceptions. | 4160 // Clear any pending exceptions. |
4158 __ li(t1, Operand(isolate->factory()->the_hole_value())); | 4161 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); |
4159 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 4162 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
4160 isolate))); | 4163 isolate))); |
4161 __ sw(t1, MemOperand(t0)); | 4164 __ sw(t1, MemOperand(t0)); |
4162 | 4165 |
4163 // Invoke the function by calling through JS entry trampoline builtin. | 4166 // Invoke the function by calling through JS entry trampoline builtin. |
4164 // Notice that we cannot store a reference to the trampoline code directly in | 4167 // Notice that we cannot store a reference to the trampoline code directly in |
4165 // this stub, because runtime stubs are not traversed when doing GC. | 4168 // this stub, because runtime stubs are not traversed when doing GC. |
4166 | 4169 |
4167 // Registers: | 4170 // Registers: |
4168 // a0: entry_address | 4171 // a0: entry_address |
(...skipping 23 matching lines...) Expand all Loading... |
4192 __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag); | 4195 __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag); |
4193 __ Call(t9); | 4196 __ Call(t9); |
4194 | 4197 |
4195 // Unlink this frame from the handler chain. | 4198 // Unlink this frame from the handler chain. |
4196 __ PopTryHandler(); | 4199 __ PopTryHandler(); |
4197 | 4200 |
4198 __ bind(&exit); // v0 holds result | 4201 __ bind(&exit); // v0 holds result |
4199 // Check if the current stack frame is marked as the outermost JS frame. | 4202 // Check if the current stack frame is marked as the outermost JS frame. |
4200 Label non_outermost_js_2; | 4203 Label non_outermost_js_2; |
4201 __ pop(t1); | 4204 __ pop(t1); |
4202 __ Branch(&non_outermost_js_2, ne, t1, | 4205 __ Branch(&non_outermost_js_2, |
| 4206 ne, |
| 4207 t1, |
4203 Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 4208 Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
4204 __ li(t1, Operand(ExternalReference(js_entry_sp))); | 4209 __ li(t1, Operand(ExternalReference(js_entry_sp))); |
4205 __ sw(zero_reg, MemOperand(t1)); | 4210 __ sw(zero_reg, MemOperand(t1)); |
4206 __ bind(&non_outermost_js_2); | 4211 __ bind(&non_outermost_js_2); |
4207 | 4212 |
4208 // Restore the top frame descriptors from the stack. | 4213 // Restore the top frame descriptors from the stack. |
4209 __ pop(t1); | 4214 __ pop(t1); |
4210 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, | 4215 __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, |
4211 isolate))); | 4216 isolate))); |
4212 __ sw(t1, MemOperand(t0)); | 4217 __ sw(t1, MemOperand(t0)); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4357 | 4362 |
4358 Label object_not_null, object_not_null_or_smi; | 4363 Label object_not_null, object_not_null_or_smi; |
4359 __ bind(¬_js_object); | 4364 __ bind(¬_js_object); |
4360 // Before null, smi and string value checks, check that the rhs is a function | 4365 // Before null, smi and string value checks, check that the rhs is a function |
4361 // as for a non-function rhs an exception needs to be thrown. | 4366 // as for a non-function rhs an exception needs to be thrown. |
4362 __ JumpIfSmi(function, &slow); | 4367 __ JumpIfSmi(function, &slow); |
4363 __ GetObjectType(function, scratch2, scratch); | 4368 __ GetObjectType(function, scratch2, scratch); |
4364 __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE)); | 4369 __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE)); |
4365 | 4370 |
4366 // Null is not instance of anything. | 4371 // Null is not instance of anything. |
4367 __ Branch(&object_not_null, ne, scratch, | 4372 __ Branch(&object_not_null, |
4368 Operand(masm->isolate()->factory()->null_value())); | 4373 ne, |
| 4374 scratch, |
| 4375 Operand(masm->isolate()->factory()->null_value())); |
4369 __ li(v0, Operand(Smi::FromInt(1))); | 4376 __ li(v0, Operand(Smi::FromInt(1))); |
4370 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); | 4377 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); |
4371 | 4378 |
4372 __ bind(&object_not_null); | 4379 __ bind(&object_not_null); |
4373 // Smi values are not instances of anything. | 4380 // Smi values are not instances of anything. |
4374 __ JumpIfNotSmi(object, &object_not_null_or_smi); | 4381 __ JumpIfNotSmi(object, &object_not_null_or_smi); |
4375 __ li(v0, Operand(Smi::FromInt(1))); | 4382 __ li(v0, Operand(Smi::FromInt(1))); |
4376 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); | 4383 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); |
4377 | 4384 |
4378 __ bind(&object_not_null_or_smi); | 4385 __ bind(&object_not_null_or_smi); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4463 | 4470 |
4464 | 4471 |
4465 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) { | 4472 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) { |
4466 // sp[0] : number of parameters | 4473 // sp[0] : number of parameters |
4467 // sp[4] : receiver displacement | 4474 // sp[4] : receiver displacement |
4468 // sp[8] : function | 4475 // sp[8] : function |
4469 // Check if the calling frame is an arguments adaptor frame. | 4476 // Check if the calling frame is an arguments adaptor frame. |
4470 Label runtime; | 4477 Label runtime; |
4471 __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 4478 __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
4472 __ lw(a2, MemOperand(a3, StandardFrameConstants::kContextOffset)); | 4479 __ lw(a2, MemOperand(a3, StandardFrameConstants::kContextOffset)); |
4473 __ Branch(&runtime, ne, | 4480 __ Branch(&runtime, |
4474 a2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 4481 ne, |
| 4482 a2, |
| 4483 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
4475 | 4484 |
4476 // Patch the arguments.length and the parameters pointer in the current frame. | 4485 // Patch the arguments.length and the parameters pointer in the current frame. |
4477 __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 4486 __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
4478 __ sw(a2, MemOperand(sp, 0 * kPointerSize)); | 4487 __ sw(a2, MemOperand(sp, 0 * kPointerSize)); |
4479 __ sll(t3, a2, 1); | 4488 __ sll(t3, a2, 1); |
4480 __ Addu(a3, a3, Operand(t3)); | 4489 __ Addu(a3, a3, Operand(t3)); |
4481 __ addiu(a3, a3, StandardFrameConstants::kCallerSPOffset); | 4490 __ addiu(a3, a3, StandardFrameConstants::kCallerSPOffset); |
4482 __ sw(a3, MemOperand(sp, 1 * kPointerSize)); | 4491 __ sw(a3, MemOperand(sp, 1 * kPointerSize)); |
4483 | 4492 |
4484 __ bind(&runtime); | 4493 __ bind(&runtime); |
(...skipping 11 matching lines...) Expand all Loading... |
4496 // t5 : mapped parameter count (tagged) | 4505 // t5 : mapped parameter count (tagged) |
4497 | 4506 |
4498 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); | 4507 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); |
4499 // a1 = parameter count (tagged) | 4508 // a1 = parameter count (tagged) |
4500 | 4509 |
4501 // Check if the calling frame is an arguments adaptor frame. | 4510 // Check if the calling frame is an arguments adaptor frame. |
4502 Label runtime; | 4511 Label runtime; |
4503 Label adaptor_frame, try_allocate; | 4512 Label adaptor_frame, try_allocate; |
4504 __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 4513 __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
4505 __ lw(a2, MemOperand(a3, StandardFrameConstants::kContextOffset)); | 4514 __ lw(a2, MemOperand(a3, StandardFrameConstants::kContextOffset)); |
4506 __ Branch(&adaptor_frame, eq, a2, | 4515 __ Branch(&adaptor_frame, |
| 4516 eq, |
| 4517 a2, |
4507 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 4518 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
4508 | 4519 |
4509 // No adaptor, parameter count = argument count. | 4520 // No adaptor, parameter count = argument count. |
4510 __ mov(a2, a1); | 4521 __ mov(a2, a1); |
4511 __ b(&try_allocate); | 4522 __ b(&try_allocate); |
4512 __ nop(); // Branch delay slot nop. | 4523 __ nop(); // Branch delay slot nop. |
4513 | 4524 |
4514 // We have an adaptor frame. Patch the parameters pointer. | 4525 // We have an adaptor frame. Patch the parameters pointer. |
4515 __ bind(&adaptor_frame); | 4526 __ bind(&adaptor_frame); |
4516 __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 4527 __ lw(a2, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5109 __ LeaveExitFrame(false, no_reg); | 5120 __ LeaveExitFrame(false, no_reg); |
5110 | 5121 |
5111 // v0: result | 5122 // v0: result |
5112 // subject: subject string (callee saved) | 5123 // subject: subject string (callee saved) |
5113 // regexp_data: RegExp data (callee saved) | 5124 // regexp_data: RegExp data (callee saved) |
5114 // last_match_info_elements: Last match info elements (callee saved) | 5125 // last_match_info_elements: Last match info elements (callee saved) |
5115 | 5126 |
5116 // Check the result. | 5127 // Check the result. |
5117 | 5128 |
5118 Label success; | 5129 Label success; |
5119 __ Branch(&success, eq, | 5130 __ Branch(&success, eq, v0, Operand(NativeRegExpMacroAssembler::SUCCESS)); |
5120 v0, Operand(NativeRegExpMacroAssembler::SUCCESS)); | |
5121 Label failure; | 5131 Label failure; |
5122 __ Branch(&failure, eq, | 5132 __ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE)); |
5123 v0, Operand(NativeRegExpMacroAssembler::FAILURE)); | |
5124 // If not exception it can only be retry. Handle that in the runtime system. | 5133 // If not exception it can only be retry. Handle that in the runtime system. |
5125 __ Branch(&runtime, ne, | 5134 __ Branch(&runtime, ne, v0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); |
5126 v0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); | |
5127 // Result must now be exception. If there is no pending exception already a | 5135 // Result must now be exception. If there is no pending exception already a |
5128 // stack overflow (on the backtrack stack) was detected in RegExp code but | 5136 // stack overflow (on the backtrack stack) was detected in RegExp code but |
5129 // haven't created the exception yet. Handle that in the runtime system. | 5137 // haven't created the exception yet. Handle that in the runtime system. |
5130 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 5138 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
5131 __ li(a1, Operand(isolate->factory()->the_hole_value())); | 5139 __ li(a1, Operand(isolate->factory()->the_hole_value())); |
5132 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 5140 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
5133 isolate))); | 5141 isolate))); |
5134 __ lw(v0, MemOperand(a2, 0)); | 5142 __ lw(v0, MemOperand(a2, 0)); |
5135 __ Branch(&runtime, eq, v0, Operand(a1)); | 5143 __ Branch(&runtime, eq, v0, Operand(a1)); |
5136 | 5144 |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5872 __ Subu(scratch, c2, Operand(static_cast<int>('0'))); | 5880 __ Subu(scratch, c2, Operand(static_cast<int>('0'))); |
5873 | 5881 |
5874 // If check failed combine both characters into single halfword. | 5882 // If check failed combine both characters into single halfword. |
5875 // This is required by the contract of the method: code at the | 5883 // This is required by the contract of the method: code at the |
5876 // not_found branch expects this combination in c1 register. | 5884 // not_found branch expects this combination in c1 register. |
5877 Label tmp; | 5885 Label tmp; |
5878 __ sll(scratch1, c2, kBitsPerByte); | 5886 __ sll(scratch1, c2, kBitsPerByte); |
5879 __ Branch(&tmp, Ugreater, scratch, Operand(static_cast<int>('9' - '0'))); | 5887 __ Branch(&tmp, Ugreater, scratch, Operand(static_cast<int>('9' - '0'))); |
5880 __ Or(c1, c1, scratch1); | 5888 __ Or(c1, c1, scratch1); |
5881 __ bind(&tmp); | 5889 __ bind(&tmp); |
5882 __ Branch(not_found, | 5890 __ Branch( |
5883 Uless_equal, | 5891 not_found, Uless_equal, scratch, Operand(static_cast<int>('9' - '0'))); |
5884 scratch, | |
5885 Operand(static_cast<int>('9' - '0'))); | |
5886 | 5892 |
5887 __ bind(¬_array_index); | 5893 __ bind(¬_array_index); |
5888 // Calculate the two character string hash. | 5894 // Calculate the two character string hash. |
5889 Register hash = scratch1; | 5895 Register hash = scratch1; |
5890 StringHelper::GenerateHashInit(masm, hash, c1); | 5896 StringHelper::GenerateHashInit(masm, hash, c1); |
5891 StringHelper::GenerateHashAddCharacter(masm, hash, c2); | 5897 StringHelper::GenerateHashAddCharacter(masm, hash, c2); |
5892 StringHelper::GenerateHashGetHash(masm, hash); | 5898 StringHelper::GenerateHashGetHash(masm, hash); |
5893 | 5899 |
5894 // Collect the two characters in a register. | 5900 // Collect the two characters in a register. |
5895 Register chars = c1; | 5901 Register chars = c1; |
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6546 // halfword store instruction (which assumes that processor is | 6552 // halfword store instruction (which assumes that processor is |
6547 // in a little endian mode). | 6553 // in a little endian mode). |
6548 __ li(t2, Operand(2)); | 6554 __ li(t2, Operand(2)); |
6549 __ AllocateAsciiString(v0, t2, t0, t1, t5, &call_runtime); | 6555 __ AllocateAsciiString(v0, t2, t0, t1, t5, &call_runtime); |
6550 __ sh(a2, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); | 6556 __ sh(a2, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); |
6551 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); | 6557 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); |
6552 __ DropAndRet(2); | 6558 __ DropAndRet(2); |
6553 | 6559 |
6554 __ bind(&longer_than_two); | 6560 __ bind(&longer_than_two); |
6555 // Check if resulting string will be flat. | 6561 // Check if resulting string will be flat. |
6556 __ Branch(&string_add_flat_result, lt, t2, | 6562 __ Branch(&string_add_flat_result, lt, t2, Operand(ConsString::kMinLength)); |
6557 Operand(ConsString::kMinLength)); | |
6558 // Handle exceptionally long strings in the runtime system. | 6563 // Handle exceptionally long strings in the runtime system. |
6559 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); | 6564 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); |
6560 ASSERT(IsPowerOf2(String::kMaxLength + 1)); | 6565 ASSERT(IsPowerOf2(String::kMaxLength + 1)); |
6561 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not. | 6566 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not. |
6562 __ Branch(&call_runtime, hs, t2, Operand(String::kMaxLength + 1)); | 6567 __ Branch(&call_runtime, hs, t2, Operand(String::kMaxLength + 1)); |
6563 | 6568 |
6564 // If result is not supposed to be flat, allocate a cons string object. | 6569 // If result is not supposed to be flat, allocate a cons string object. |
6565 // If both strings are ASCII the result is an ASCII cons string. | 6570 // If both strings are ASCII the result is an ASCII cons string. |
6566 if (flags_ != NO_STRING_ADD_FLAGS) { | 6571 if (flags_ != NO_STRING_ADD_FLAGS) { |
6567 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); | 6572 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7073 Label find_ra; | 7078 Label find_ra; |
7074 masm->bal(&find_ra); // ra = pc + 8. | 7079 masm->bal(&find_ra); // ra = pc + 8. |
7075 masm->nop(); // Branch delay slot nop. | 7080 masm->nop(); // Branch delay slot nop. |
7076 masm->bind(&find_ra); | 7081 masm->bind(&find_ra); |
7077 | 7082 |
7078 const int kNumInstructionsToJump = 6; | 7083 const int kNumInstructionsToJump = 6; |
7079 masm->addiu(ra, ra, kNumInstructionsToJump * kPointerSize); | 7084 masm->addiu(ra, ra, kNumInstructionsToJump * kPointerSize); |
7080 // Push return address (accessible to GC through exit frame pc). | 7085 // Push return address (accessible to GC through exit frame pc). |
7081 // This spot for ra was reserved in EnterExitFrame. | 7086 // This spot for ra was reserved in EnterExitFrame. |
7082 masm->sw(ra, MemOperand(sp, kCArgsSlotsSize)); | 7087 masm->sw(ra, MemOperand(sp, kCArgsSlotsSize)); |
7083 masm->li(ra, Operand(reinterpret_cast<intptr_t>(GetCode().location()), | 7088 masm->li(ra, |
7084 RelocInfo::CODE_TARGET), true); | 7089 Operand(reinterpret_cast<intptr_t>(GetCode().location()), |
| 7090 RelocInfo::CODE_TARGET), |
| 7091 CONSTANT_SIZE); |
7085 // Call the function. | 7092 // Call the function. |
7086 masm->Jump(t9); | 7093 masm->Jump(t9); |
7087 // Make sure the stored 'ra' points to this position. | 7094 // Make sure the stored 'ra' points to this position. |
7088 ASSERT_EQ(kNumInstructionsToJump, masm->InstructionsGeneratedSince(&find_ra)); | 7095 ASSERT_EQ(kNumInstructionsToJump, masm->InstructionsGeneratedSince(&find_ra)); |
7089 } | 7096 } |
7090 | 7097 |
7091 | 7098 |
7092 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, | 7099 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, |
7093 Label* miss, | 7100 Label* miss, |
7094 Label* done, | 7101 Label* done, |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7682 __ Ret(USE_DELAY_SLOT); | 7689 __ Ret(USE_DELAY_SLOT); |
7683 __ mov(v0, a0); | 7690 __ mov(v0, a0); |
7684 } | 7691 } |
7685 | 7692 |
7686 | 7693 |
7687 #undef __ | 7694 #undef __ |
7688 | 7695 |
7689 } } // namespace v8::internal | 7696 } } // namespace v8::internal |
7690 | 7697 |
7691 #endif // V8_TARGET_ARCH_MIPS | 7698 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |