| 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 |