Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 6489001: Change native RegExp call code to properly set C++ structures and (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build-x64
Patch Set: Ob-lintfix. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3281 matching lines...) Expand 10 before | Expand all | Expand 10 after
3292 case Token::BIT_NOT: 3292 case Token::BIT_NOT:
3293 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_JS); 3293 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_JS);
3294 break; 3294 break;
3295 default: 3295 default:
3296 UNREACHABLE(); 3296 UNREACHABLE();
3297 } 3297 }
3298 } 3298 }
3299 3299
3300 3300
3301 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { 3301 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
3302 // r0 holds the exception. 3302 __ Throw(r0);
3303
3304 // Adjust this code if not the case.
3305 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
3306
3307 // Drop the sp to the top of the handler.
3308 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
3309 __ ldr(sp, MemOperand(r3));
3310
3311 // Restore the next handler and frame pointer, discard handler state.
3312 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
3313 __ pop(r2);
3314 __ str(r2, MemOperand(r3));
3315 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
3316 __ ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state.
3317
3318 // Before returning we restore the context from the frame pointer if
3319 // not NULL. The frame pointer is NULL in the exception handler of a
3320 // JS entry frame.
3321 __ cmp(fp, Operand(0, RelocInfo::NONE));
3322 // Set cp to NULL if fp is NULL.
3323 __ mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
3324 // Restore cp otherwise.
3325 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
3326 #ifdef DEBUG
3327 if (FLAG_debug_code) {
3328 __ mov(lr, Operand(pc));
3329 }
3330 #endif
3331 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
3332 __ pop(pc);
3333 } 3303 }
3334 3304
3335 3305
3336 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, 3306 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
3337 UncatchableExceptionType type) { 3307 UncatchableExceptionType type) {
3338 // Adjust this code if not the case. 3308 __ ThrowUncatchable(type, r0);
3339 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
3340
3341 // Drop sp to the top stack handler.
3342 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
3343 __ ldr(sp, MemOperand(r3));
3344
3345 // Unwind the handlers until the ENTRY handler is found.
3346 Label loop, done;
3347 __ bind(&loop);
3348 // Load the type of the current stack handler.
3349 const int kStateOffset = StackHandlerConstants::kStateOffset;
3350 __ ldr(r2, MemOperand(sp, kStateOffset));
3351 __ cmp(r2, Operand(StackHandler::ENTRY));
3352 __ b(eq, &done);
3353 // Fetch the next handler in the list.
3354 const int kNextOffset = StackHandlerConstants::kNextOffset;
3355 __ ldr(sp, MemOperand(sp, kNextOffset));
3356 __ jmp(&loop);
3357 __ bind(&done);
3358
3359 // Set the top handler address to next handler past the current ENTRY handler.
3360 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
3361 __ pop(r2);
3362 __ str(r2, MemOperand(r3));
3363
3364 if (type == OUT_OF_MEMORY) {
3365 // Set external caught exception to false.
3366 ExternalReference external_caught(Top::k_external_caught_exception_address);
3367 __ mov(r0, Operand(false, RelocInfo::NONE));
3368 __ mov(r2, Operand(external_caught));
3369 __ str(r0, MemOperand(r2));
3370
3371 // Set pending exception and r0 to out of memory exception.
3372 Failure* out_of_memory = Failure::OutOfMemoryException();
3373 __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
3374 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
3375 __ str(r0, MemOperand(r2));
3376 }
3377
3378 // Stack layout at this point. See also StackHandlerConstants.
3379 // sp -> state (ENTRY)
3380 // fp
3381 // lr
3382
3383 // Discard handler state (r2 is not used) and restore frame pointer.
3384 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
3385 __ ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state.
3386 // Before returning we restore the context from the frame pointer if
3387 // not NULL. The frame pointer is NULL in the exception handler of a
3388 // JS entry frame.
3389 __ cmp(fp, Operand(0, RelocInfo::NONE));
3390 // Set cp to NULL if fp is NULL.
3391 __ mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
3392 // Restore cp otherwise.
3393 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
3394 #ifdef DEBUG
3395 if (FLAG_debug_code) {
3396 __ mov(lr, Operand(pc));
3397 }
3398 #endif
3399 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
3400 __ pop(pc);
3401 } 3309 }
3402 3310
3403 3311
3404 void CEntryStub::GenerateCore(MacroAssembler* masm, 3312 void CEntryStub::GenerateCore(MacroAssembler* masm,
3405 Label* throw_normal_exception, 3313 Label* throw_normal_exception,
3406 Label* throw_termination_exception, 3314 Label* throw_termination_exception,
3407 Label* throw_out_of_memory_exception, 3315 Label* throw_out_of_memory_exception,
3408 bool do_gc, 3316 bool do_gc,
3409 bool always_allocate) { 3317 bool always_allocate) {
3410 // r0: result parameter for PerformGC, if any 3318 // r0: result parameter for PerformGC, if any
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3477 STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); 3385 STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
3478 // Lower 2 bits of r2 are 0 iff r0 has failure tag. 3386 // Lower 2 bits of r2 are 0 iff r0 has failure tag.
3479 __ add(r2, r0, Operand(1)); 3387 __ add(r2, r0, Operand(1));
3480 __ tst(r2, Operand(kFailureTagMask)); 3388 __ tst(r2, Operand(kFailureTagMask));
3481 __ b(eq, &failure_returned); 3389 __ b(eq, &failure_returned);
3482 3390
3483 // Exit C frame and return. 3391 // Exit C frame and return.
3484 // r0:r1: result 3392 // r0:r1: result
3485 // sp: stack pointer 3393 // sp: stack pointer
3486 // fp: frame pointer 3394 // fp: frame pointer
3487 __ LeaveExitFrame(save_doubles_); 3395 // Callee-saved register r4 still holds argc.
3396 __ LeaveExitFrame(save_doubles_, r4);
3397 __ mov(pc, lr);
3488 3398
3489 // check if we should retry or throw exception 3399 // check if we should retry or throw exception
3490 Label retry; 3400 Label retry;
3491 __ bind(&failure_returned); 3401 __ bind(&failure_returned);
3492 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0); 3402 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
3493 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); 3403 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
3494 __ b(eq, &retry); 3404 __ b(eq, &retry);
3495 3405
3496 // Special handling of out of memory exceptions. 3406 // Special handling of out of memory exceptions.
3497 Failure* out_of_memory = Failure::OutOfMemoryException(); 3407 Failure* out_of_memory = Failure::OutOfMemoryException();
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
4256 4166
4257 // r1: previous index 4167 // r1: previous index
4258 // r3: encoding of subject string (1 if ascii, 0 if two_byte); 4168 // r3: encoding of subject string (1 if ascii, 0 if two_byte);
4259 // r7: code 4169 // r7: code
4260 // subject: Subject string 4170 // subject: Subject string
4261 // regexp_data: RegExp data (FixedArray) 4171 // regexp_data: RegExp data (FixedArray)
4262 // All checks done. Now push arguments for native regexp code. 4172 // All checks done. Now push arguments for native regexp code.
4263 __ IncrementCounter(&Counters::regexp_entry_native, 1, r0, r2); 4173 __ IncrementCounter(&Counters::regexp_entry_native, 1, r0, r2);
4264 4174
4265 static const int kRegExpExecuteArguments = 7; 4175 static const int kRegExpExecuteArguments = 7;
4266 __ push(lr); 4176 static const int kParameterRegisters = 4;
4267 __ PrepareCallCFunction(kRegExpExecuteArguments, r0); 4177 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
4268 4178
4269 // Argument 7 (sp[8]): Indicate that this is a direct call from JavaScript. 4179 // Stack pointer now points to cell where return address is to be written.
4180 // Arguments are before that on the stack or in registers.
4181
4182 // Argument 7 (sp[12]): Indicate that this is a direct call from JavaScript.
4270 __ mov(r0, Operand(1)); 4183 __ mov(r0, Operand(1));
4271 __ str(r0, MemOperand(sp, 2 * kPointerSize)); 4184 __ str(r0, MemOperand(sp, 3 * kPointerSize));
4272 4185
4273 // Argument 6 (sp[4]): Start (high end) of backtracking stack memory area. 4186 // Argument 6 (sp[8]): Start (high end) of backtracking stack memory area.
4274 __ mov(r0, Operand(address_of_regexp_stack_memory_address)); 4187 __ mov(r0, Operand(address_of_regexp_stack_memory_address));
4275 __ ldr(r0, MemOperand(r0, 0)); 4188 __ ldr(r0, MemOperand(r0, 0));
4276 __ mov(r2, Operand(address_of_regexp_stack_memory_size)); 4189 __ mov(r2, Operand(address_of_regexp_stack_memory_size));
4277 __ ldr(r2, MemOperand(r2, 0)); 4190 __ ldr(r2, MemOperand(r2, 0));
4278 __ add(r0, r0, Operand(r2)); 4191 __ add(r0, r0, Operand(r2));
4192 __ str(r0, MemOperand(sp, 2 * kPointerSize));
4193
4194 // Argument 5 (sp[4]): static offsets vector buffer.
4195 __ mov(r0, Operand(ExternalReference::address_of_static_offsets_vector()));
4279 __ str(r0, MemOperand(sp, 1 * kPointerSize)); 4196 __ str(r0, MemOperand(sp, 1 * kPointerSize));
4280 4197
4281 // Argument 5 (sp[0]): static offsets vector buffer.
4282 __ mov(r0, Operand(ExternalReference::address_of_static_offsets_vector()));
4283 __ str(r0, MemOperand(sp, 0 * kPointerSize));
4284
4285 // For arguments 4 and 3 get string length, calculate start of string data and 4198 // For arguments 4 and 3 get string length, calculate start of string data and
4286 // calculate the shift of the index (0 for ASCII and 1 for two byte). 4199 // calculate the shift of the index (0 for ASCII and 1 for two byte).
4287 __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset)); 4200 __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset));
4288 __ mov(r0, Operand(r0, ASR, kSmiTagSize)); 4201 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
4289 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); 4202 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize);
4290 __ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 4203 __ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
4291 __ eor(r3, r3, Operand(1)); 4204 __ eor(r3, r3, Operand(1));
4292 // Argument 4 (r3): End of string data 4205 // Argument 4 (r3): End of string data
4293 // Argument 3 (r2): Start of string data 4206 // Argument 3 (r2): Start of string data
4294 __ add(r2, r9, Operand(r1, LSL, r3)); 4207 __ add(r2, r9, Operand(r1, LSL, r3));
4295 __ add(r3, r9, Operand(r0, LSL, r3)); 4208 __ add(r3, r9, Operand(r0, LSL, r3));
4296 4209
4297 // Argument 2 (r1): Previous index. 4210 // Argument 2 (r1): Previous index.
4298 // Already there 4211 // Already there
4299 4212
4300 // Argument 1 (r0): Subject string. 4213 // Argument 1 (r0): Subject string.
4301 __ mov(r0, subject); 4214 __ mov(r0, subject);
4302 4215
4303 // Locate the code entry and call it. 4216 // Locate the code entry and call it.
4304 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); 4217 __ add(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
4305 __ CallCFunction(r7, kRegExpExecuteArguments); 4218 DirectCEntryStub stub;
4306 __ pop(lr); 4219 stub.GenerateCall(masm, r7);
4220
4221 __ LeaveExitFrame(false, no_reg);
4307 4222
4308 // r0: result 4223 // r0: result
4309 // subject: subject string (callee saved) 4224 // subject: subject string (callee saved)
4310 // regexp_data: RegExp data (callee saved) 4225 // regexp_data: RegExp data (callee saved)
4311 // last_match_info_elements: Last match info elements (callee saved) 4226 // last_match_info_elements: Last match info elements (callee saved)
4312 4227
4313 // Check the result. 4228 // Check the result.
4314 Label success; 4229 Label success;
4230
4315 __ cmp(r0, Operand(NativeRegExpMacroAssembler::SUCCESS)); 4231 __ cmp(r0, Operand(NativeRegExpMacroAssembler::SUCCESS));
4316 __ b(eq, &success); 4232 __ b(eq, &success);
4317 Label failure; 4233 Label failure;
4318 __ cmp(r0, Operand(NativeRegExpMacroAssembler::FAILURE)); 4234 __ cmp(r0, Operand(NativeRegExpMacroAssembler::FAILURE));
4319 __ b(eq, &failure); 4235 __ b(eq, &failure);
4320 __ cmp(r0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); 4236 __ cmp(r0, Operand(NativeRegExpMacroAssembler::EXCEPTION));
4321 // If not exception it can only be retry. Handle that in the runtime system. 4237 // If not exception it can only be retry. Handle that in the runtime system.
4322 __ b(ne, &runtime); 4238 __ b(ne, &runtime);
4323 // Result must now be exception. If there is no pending exception already a 4239 // Result must now be exception. If there is no pending exception already a
4324 // stack overflow (on the backtrack stack) was detected in RegExp code but 4240 // stack overflow (on the backtrack stack) was detected in RegExp code but
4325 // haven't created the exception yet. Handle that in the runtime system. 4241 // haven't created the exception yet. Handle that in the runtime system.
4326 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 4242 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
4327 __ mov(r0, Operand(ExternalReference::the_hole_value_location())); 4243 __ mov(r1, Operand(ExternalReference::the_hole_value_location()));
4328 __ ldr(r0, MemOperand(r0, 0));
4329 __ mov(r1, Operand(ExternalReference(Top::k_pending_exception_address)));
4330 __ ldr(r1, MemOperand(r1, 0)); 4244 __ ldr(r1, MemOperand(r1, 0));
4245 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
4246 __ ldr(r0, MemOperand(r2, 0));
4331 __ cmp(r0, r1); 4247 __ cmp(r0, r1);
4332 __ b(eq, &runtime); 4248 __ b(eq, &runtime);
4249
4250 __ str(r1, MemOperand(r2, 0)); // Clear pending exception.
4251
4252 // Check if the exception is a termination. If so, throw as uncatchable.
4253 __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex);
4254 __ cmp(r0, ip);
4255 Label termination_exception;
4256 __ b(eq, &termination_exception);
4257
4258 __ Throw(r0); // Expects thrown value in r0.
4259
4260 __ bind(&termination_exception);
4261 __ ThrowUncatchable(TERMINATION, r0); // Expects thrown value in r0.
4262
4333 __ bind(&failure); 4263 __ bind(&failure);
4334 // For failure and exception return null. 4264 // For failure and exception return null.
4335 __ mov(r0, Operand(Factory::null_value())); 4265 __ mov(r0, Operand(Factory::null_value()));
4336 __ add(sp, sp, Operand(4 * kPointerSize)); 4266 __ add(sp, sp, Operand(4 * kPointerSize));
4337 __ Ret(); 4267 __ Ret();
4338 4268
4339 // Process the result from the native regexp code. 4269 // Process the result from the native regexp code.
4340 __ bind(&success); 4270 __ bind(&success);
4341 __ ldr(r1, 4271 __ ldr(r1,
4342 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); 4272 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
(...skipping 1603 matching lines...) Expand 10 before | Expand all | Expand 10 after
5946 5876
5947 void DirectCEntryStub::Generate(MacroAssembler* masm) { 5877 void DirectCEntryStub::Generate(MacroAssembler* masm) {
5948 __ ldr(pc, MemOperand(sp, 0)); 5878 __ ldr(pc, MemOperand(sp, 0));
5949 } 5879 }
5950 5880
5951 5881
5952 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, 5882 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
5953 ApiFunction *function) { 5883 ApiFunction *function) {
5954 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()), 5884 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()),
5955 RelocInfo::CODE_TARGET)); 5885 RelocInfo::CODE_TARGET));
5956 // Push return address (accessible to GC through exit frame pc).
5957 __ mov(r2, 5886 __ mov(r2,
5958 Operand(ExternalReference(function, ExternalReference::DIRECT_CALL))); 5887 Operand(ExternalReference(function, ExternalReference::DIRECT_CALL)));
5888 // Push return address (accessible to GC through exit frame pc).
5959 __ str(pc, MemOperand(sp, 0)); 5889 __ str(pc, MemOperand(sp, 0));
5960 __ Jump(r2); // Call the api function. 5890 __ Jump(r2); // Call the api function.
5961 } 5891 }
5962 5892
5963 5893
5894 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
5895 Register target) {
5896 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()),
5897 RelocInfo::CODE_TARGET));
5898 // Push return address (accessible to GC through exit frame pc).
5899 __ str(pc, MemOperand(sp, 0));
5900 __ Jump(target); // Call the C++ function.
5901 }
5902
5903
5964 void GenerateFastPixelArrayLoad(MacroAssembler* masm, 5904 void GenerateFastPixelArrayLoad(MacroAssembler* masm,
5965 Register receiver, 5905 Register receiver,
5966 Register key, 5906 Register key,
5967 Register elements_map, 5907 Register elements_map,
5968 Register elements, 5908 Register elements,
5969 Register scratch1, 5909 Register scratch1,
5970 Register scratch2, 5910 Register scratch2,
5971 Register result, 5911 Register result,
5972 Label* not_pixel_array, 5912 Label* not_pixel_array,
5973 Label* key_not_smi, 5913 Label* key_not_smi,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
6026 __ SmiTag(r0, scratch1); 5966 __ SmiTag(r0, scratch1);
6027 __ Ret(); 5967 __ Ret();
6028 } 5968 }
6029 5969
6030 5970
6031 #undef __ 5971 #undef __
6032 5972
6033 } } // namespace v8::internal 5973 } } // namespace v8::internal
6034 5974
6035 #endif // V8_TARGET_ARCH_ARM 5975 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698