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

Side by Side Diff: src/x64/code-stubs-x64.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/macro-assembler.h ('k') | src/x64/macro-assembler-x64.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 2250 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset)); 2261 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
2262 // Calculate number of capture registers (number_of_captures + 1) * 2. 2262 // Calculate number of capture registers (number_of_captures + 1) * 2.
2263 __ leal(rdx, Operand(rdx, rdx, times_1, 2)); 2263 __ leal(rdx, Operand(rdx, rdx, times_1, 2));
2264 // Check that the static offsets vector buffer is large enough. 2264 // Check that the static offsets vector buffer is large enough.
2265 __ cmpl(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize)); 2265 __ cmpl(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize));
2266 __ j(above, &runtime); 2266 __ j(above, &runtime);
2267 2267
2268 // rcx: RegExp data (FixedArray) 2268 // rcx: RegExp data (FixedArray)
2269 // rdx: Number of capture registers 2269 // rdx: Number of capture registers
2270 // Check that the second argument is a string. 2270 // Check that the second argument is a string.
2271 __ movq(rax, Operand(rsp, kSubjectOffset)); 2271 __ movq(rdi, Operand(rsp, kSubjectOffset));
2272 __ JumpIfSmi(rax, &runtime); 2272 __ JumpIfSmi(rdi, &runtime);
2273 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx); 2273 Condition is_string = masm->IsObjectStringType(rdi, rbx, rbx);
2274 __ j(NegateCondition(is_string), &runtime); 2274 __ j(NegateCondition(is_string), &runtime);
2275 2275
2276 // rax: Subject string. 2276 // rdi: Subject string.
2277 // rcx: RegExp data (FixedArray). 2277 // rax: RegExp data (FixedArray).
2278 // rdx: Number of capture registers. 2278 // rdx: Number of capture registers.
2279 // Check that the third argument is a positive smi less than the string 2279 // Check that the third argument is a positive smi less than the string
2280 // length. A negative value will be greater (unsigned comparison). 2280 // length. A negative value will be greater (unsigned comparison).
2281 __ movq(rbx, Operand(rsp, kPreviousIndexOffset)); 2281 __ movq(rbx, Operand(rsp, kPreviousIndexOffset));
2282 __ JumpIfNotSmi(rbx, &runtime); 2282 __ JumpIfNotSmi(rbx, &runtime);
2283 __ SmiCompare(rbx, FieldOperand(rax, String::kLengthOffset)); 2283 __ SmiCompare(rbx, FieldOperand(rdi, String::kLengthOffset));
2284 __ j(above_equal, &runtime); 2284 __ j(above_equal, &runtime);
2285 2285
2286 // rcx: RegExp data (FixedArray) 2286 // rax: RegExp data (FixedArray)
2287 // rdx: Number of capture registers 2287 // rdx: Number of capture registers
2288 // Check that the fourth object is a JSArray object. 2288 // Check that the fourth object is a JSArray object.
2289 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); 2289 __ movq(rdi, Operand(rsp, kLastMatchInfoOffset));
2290 __ JumpIfSmi(rax, &runtime); 2290 __ JumpIfSmi(rdi, &runtime);
2291 __ CmpObjectType(rax, JS_ARRAY_TYPE, kScratchRegister); 2291 __ CmpObjectType(rdi, JS_ARRAY_TYPE, kScratchRegister);
2292 __ j(not_equal, &runtime); 2292 __ j(not_equal, &runtime);
2293 // Check that the JSArray is in fast case. 2293 // Check that the JSArray is in fast case.
2294 __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset)); 2294 __ movq(rbx, FieldOperand(rdi, JSArray::kElementsOffset));
2295 __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset)); 2295 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
2296 __ Cmp(rax, Factory::fixed_array_map()); 2296 __ Cmp(rdi, Factory::fixed_array_map());
2297 __ j(not_equal, &runtime); 2297 __ j(not_equal, &runtime);
2298 // Check that the last match info has space for the capture registers and the 2298 // Check that the last match info has space for the capture registers and the
2299 // additional information. Ensure no overflow in add. 2299 // additional information. Ensure no overflow in add.
2300 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); 2300 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
2301 __ SmiToInteger32(rax, FieldOperand(rbx, FixedArray::kLengthOffset)); 2301 __ SmiToInteger32(rdi, FieldOperand(rbx, FixedArray::kLengthOffset));
2302 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead)); 2302 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
2303 __ cmpl(rdx, rax); 2303 __ cmpl(rdx, rdi);
2304 __ j(greater, &runtime); 2304 __ j(greater, &runtime);
2305 2305
2306 // rcx: RegExp data (FixedArray) 2306 // rax: RegExp data (FixedArray)
2307 // Check the representation and encoding of the subject string. 2307 // Check the representation and encoding of the subject string.
2308 NearLabel seq_ascii_string, seq_two_byte_string, check_code; 2308 NearLabel seq_ascii_string, seq_two_byte_string, check_code;
2309 __ movq(rax, Operand(rsp, kSubjectOffset)); 2309 __ movq(rdi, Operand(rsp, kSubjectOffset));
2310 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 2310 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2311 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 2311 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
2312 // First check for flat two byte string. 2312 // First check for flat two byte string.
2313 __ andb(rbx, Immediate( 2313 __ andb(rbx, Immediate(
2314 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask)); 2314 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask));
2315 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 2315 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
2316 __ j(zero, &seq_two_byte_string); 2316 __ j(zero, &seq_two_byte_string);
2317 // Any other flat string must be a flat ascii string. 2317 // Any other flat string must be a flat ascii string.
2318 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask)); 2318 __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
2319 __ j(zero, &seq_ascii_string); 2319 __ j(zero, &seq_ascii_string);
2320 2320
2321 // Check for flat cons string. 2321 // Check for flat cons string.
2322 // A flat cons string is a cons string where the second part is the empty 2322 // A flat cons string is a cons string where the second part is the empty
2323 // string. In that case the subject string is just the first part of the cons 2323 // string. In that case the subject string is just the first part of the cons
2324 // string. Also in this case the first part of the cons string is known to be 2324 // string. Also in this case the first part of the cons string is known to be
2325 // a sequential string or an external string. 2325 // a sequential string or an external string.
2326 STATIC_ASSERT(kExternalStringTag !=0); 2326 STATIC_ASSERT(kExternalStringTag !=0);
2327 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); 2327 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0);
2328 __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag)); 2328 __ testb(rbx, Immediate(kIsNotStringMask | kExternalStringTag));
2329 __ j(not_zero, &runtime); 2329 __ j(not_zero, &runtime);
2330 // String is a cons string. 2330 // String is a cons string.
2331 __ movq(rdx, FieldOperand(rax, ConsString::kSecondOffset)); 2331 __ movq(rdx, FieldOperand(rdi, ConsString::kSecondOffset));
2332 __ Cmp(rdx, Factory::empty_string()); 2332 __ Cmp(rdx, Factory::empty_string());
2333 __ j(not_equal, &runtime); 2333 __ j(not_equal, &runtime);
2334 __ movq(rax, FieldOperand(rax, ConsString::kFirstOffset)); 2334 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
2335 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 2335 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
2336 // String is a cons string with empty second part. 2336 // String is a cons string with empty second part.
2337 // rax: first part of cons string. 2337 // rdi: first part of cons string.
2338 // rbx: map of first part of cons string. 2338 // rbx: map of first part of cons string.
2339 // Is first part a flat two byte string? 2339 // Is first part a flat two byte string?
2340 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2340 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2341 Immediate(kStringRepresentationMask | kStringEncodingMask)); 2341 Immediate(kStringRepresentationMask | kStringEncodingMask));
2342 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 2342 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
2343 __ j(zero, &seq_two_byte_string); 2343 __ j(zero, &seq_two_byte_string);
2344 // Any other flat string must be ascii. 2344 // Any other flat string must be ascii.
2345 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 2345 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
2346 Immediate(kStringRepresentationMask)); 2346 Immediate(kStringRepresentationMask));
2347 __ j(not_zero, &runtime); 2347 __ j(not_zero, &runtime);
2348 2348
2349 __ bind(&seq_ascii_string); 2349 __ bind(&seq_ascii_string);
2350 // rax: subject string (sequential ascii) 2350 // rdi: subject string (sequential ascii)
2351 // rcx: RegExp data (FixedArray) 2351 // rax: RegExp data (FixedArray)
2352 __ movq(r11, FieldOperand(rcx, JSRegExp::kDataAsciiCodeOffset)); 2352 __ movq(r11, FieldOperand(rax, JSRegExp::kDataAsciiCodeOffset));
2353 __ Set(rdi, 1); // Type is ascii. 2353 __ Set(rcx, 1); // Type is ascii.
2354 __ jmp(&check_code); 2354 __ jmp(&check_code);
2355 2355
2356 __ bind(&seq_two_byte_string); 2356 __ bind(&seq_two_byte_string);
2357 // rax: subject string (flat two-byte) 2357 // rdi: subject string (flat two-byte)
2358 // rcx: RegExp data (FixedArray) 2358 // rax: RegExp data (FixedArray)
2359 __ movq(r11, FieldOperand(rcx, JSRegExp::kDataUC16CodeOffset)); 2359 __ movq(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset));
2360 __ Set(rdi, 0); // Type is two byte. 2360 __ Set(rcx, 0); // Type is two byte.
2361 2361
2362 __ bind(&check_code); 2362 __ bind(&check_code);
2363 // Check that the irregexp code has been generated for the actual string 2363 // Check that the irregexp code has been generated for the actual string
2364 // encoding. If it has, the field contains a code object otherwise it contains 2364 // encoding. If it has, the field contains a code object otherwise it contains
2365 // the hole. 2365 // the hole.
2366 __ CmpObjectType(r11, CODE_TYPE, kScratchRegister); 2366 __ CmpObjectType(r11, CODE_TYPE, kScratchRegister);
2367 __ j(not_equal, &runtime); 2367 __ j(not_equal, &runtime);
2368 2368
2369 // rax: subject string 2369 // rdi: subject string
2370 // rdi: encoding of subject string (1 if ascii, 0 if two_byte); 2370 // rcx: encoding of subject string (1 if ascii, 0 if two_byte);
2371 // r11: code 2371 // r11: code
2372 // Load used arguments before starting to push arguments for call to native 2372 // Load used arguments before starting to push arguments for call to native
2373 // RegExp code to avoid handling changing stack height. 2373 // RegExp code to avoid handling changing stack height.
2374 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset)); 2374 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset));
2375 2375
2376 // rax: subject string 2376 // rdi: subject string
2377 // rbx: previous index 2377 // rbx: previous index
2378 // rdi: encoding of subject string (1 if ascii 0 if two_byte); 2378 // rcx: encoding of subject string (1 if ascii 0 if two_byte);
2379 // r11: code 2379 // r11: code
2380 // All checks done. Now push arguments for native regexp code. 2380 // All checks done. Now push arguments for native regexp code.
2381 __ IncrementCounter(&Counters::regexp_entry_native, 1); 2381 __ IncrementCounter(&Counters::regexp_entry_native, 1);
2382 2382
2383 // rsi is caller save on Windows and used to pass parameter on Linux.
2384 __ push(rsi);
2385
2386 static const int kRegExpExecuteArguments = 7; 2383 static const int kRegExpExecuteArguments = 7;
2387 __ PrepareCallCFunction(kRegExpExecuteArguments);
2388 int argument_slots_on_stack = 2384 int argument_slots_on_stack =
2389 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); 2385 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
2386 __ EnterApiExitFrame(argument_slots_on_stack); // Clobbers rax!
2390 2387
2391 // Argument 7: Indicate that this is a direct call from JavaScript. 2388 // Argument 7: Indicate that this is a direct call from JavaScript.
2392 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), 2389 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
2393 Immediate(1)); 2390 Immediate(1));
2394 2391
2395 // Argument 6: Start (high end) of backtracking stack memory area. 2392 // Argument 6: Start (high end) of backtracking stack memory area.
2396 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); 2393 __ movq(kScratchRegister, address_of_regexp_stack_memory_address);
2397 __ movq(r9, Operand(kScratchRegister, 0)); 2394 __ movq(r9, Operand(kScratchRegister, 0));
2398 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 2395 __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
2399 __ addq(r9, Operand(kScratchRegister, 0)); 2396 __ addq(r9, Operand(kScratchRegister, 0));
(...skipping 16 matching lines...) Expand all
2416 Register arg2 = rdx; 2413 Register arg2 = rdx;
2417 Register arg1 = rcx; 2414 Register arg1 = rcx;
2418 #else 2415 #else
2419 Register arg4 = rcx; 2416 Register arg4 = rcx;
2420 Register arg3 = rdx; 2417 Register arg3 = rdx;
2421 Register arg2 = rsi; 2418 Register arg2 = rsi;
2422 Register arg1 = rdi; 2419 Register arg1 = rdi;
2423 #endif 2420 #endif
2424 2421
2425 // Keep track on aliasing between argX defined above and the registers used. 2422 // Keep track on aliasing between argX defined above and the registers used.
2426 // rax: subject string 2423 // rdi: subject string
2427 // rbx: previous index 2424 // rbx: previous index
2428 // rdi: encoding of subject string (1 if ascii 0 if two_byte); 2425 // rcx: encoding of subject string (1 if ascii 0 if two_byte);
2429 // r11: code 2426 // r11: code
2430 2427
2431 // Argument 4: End of string data 2428 // Argument 4: End of string data
2432 // Argument 3: Start of string data 2429 // Argument 3: Start of string data
2433 NearLabel setup_two_byte, setup_rest; 2430 NearLabel setup_two_byte, setup_rest;
2434 __ testb(rdi, rdi); 2431 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string.
2435 __ j(zero, &setup_two_byte); 2432 __ j(zero, &setup_two_byte);
2436 __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); 2433 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
2437 __ lea(arg4, FieldOperand(rax, rdi, times_1, SeqAsciiString::kHeaderSize)); 2434 __ lea(arg4, FieldOperand(rdi, rcx, times_1, SeqAsciiString::kHeaderSize));
2438 __ lea(arg3, FieldOperand(rax, rbx, times_1, SeqAsciiString::kHeaderSize)); 2435 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize));
2439 __ jmp(&setup_rest); 2436 __ jmp(&setup_rest);
2440 __ bind(&setup_two_byte); 2437 __ bind(&setup_two_byte);
2441 __ SmiToInteger32(rdi, FieldOperand(rax, String::kLengthOffset)); 2438 __ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
2442 __ lea(arg4, FieldOperand(rax, rdi, times_2, SeqTwoByteString::kHeaderSize)); 2439 __ lea(arg4, FieldOperand(rdi, rcx, times_2, SeqTwoByteString::kHeaderSize));
2443 __ lea(arg3, FieldOperand(rax, rbx, times_2, SeqTwoByteString::kHeaderSize)); 2440 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));
2444 2441
2445 __ bind(&setup_rest); 2442 __ bind(&setup_rest);
2446 // Argument 2: Previous index. 2443 // Argument 2: Previous index.
2447 __ movq(arg2, rbx); 2444 __ movq(arg2, rbx);
2448 2445
2449 // Argument 1: Subject string. 2446 // Argument 1: Subject string.
2450 __ movq(arg1, rax); 2447 #ifdef WIN64_
2448 __ movq(arg1, rdi);
2449 #else
2450 // Already there in AMD64 calling convention.
2451 ASSERT(arg1.is(rdi));
2452 #endif
2451 2453
2452 // Locate the code entry and call it. 2454 // Locate the code entry and call it.
2453 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag)); 2455 __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
2454 __ CallCFunction(r11, kRegExpExecuteArguments); 2456 __ call(r11);
2455 2457
2456 // rsi is caller save, as it is used to pass parameter. 2458 __ LeaveApiExitFrame();
2457 __ pop(rsi);
2458 2459
2459 // Check the result. 2460 // Check the result.
2460 NearLabel success; 2461 NearLabel success;
2462 Label exception;
2461 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS)); 2463 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS));
2462 __ j(equal, &success); 2464 __ j(equal, &success);
2463 NearLabel failure; 2465 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION));
2466 __ j(equal, &exception);
2464 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::FAILURE)); 2467 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::FAILURE));
2465 __ j(equal, &failure); 2468 // If none of the above, it can only be retry.
2466 __ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION)); 2469 // Handle that in the runtime system.
2467 // If not exception it can only be retry. Handle that in the runtime system.
2468 __ j(not_equal, &runtime); 2470 __ j(not_equal, &runtime);
2469 // Result must now be exception. If there is no pending exception already a 2471
2470 // stack overflow (on the backtrack stack) was detected in RegExp code but 2472 // For failure return null.
2471 // haven't created the exception yet. Handle that in the runtime system. 2473 __ LoadRoot(rax, Heap::kNullValueRootIndex);
2472 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
2473 ExternalReference pending_exception_address(Top::k_pending_exception_address);
2474 __ movq(kScratchRegister, pending_exception_address);
2475 __ Cmp(kScratchRegister, Factory::the_hole_value());
2476 __ j(equal, &runtime);
2477 __ bind(&failure);
2478 // For failure and exception return null.
2479 __ Move(rax, Factory::null_value());
2480 __ ret(4 * kPointerSize); 2474 __ ret(4 * kPointerSize);
2481 2475
2482 // Load RegExp data. 2476 // Load RegExp data.
2483 __ bind(&success); 2477 __ bind(&success);
2484 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2478 __ movq(rax, Operand(rsp, kJSRegExpOffset));
2485 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset)); 2479 __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
2486 __ SmiToInteger32(rax, 2480 __ SmiToInteger32(rax,
2487 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset)); 2481 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
2488 // Calculate number of capture registers (number_of_captures + 1) * 2. 2482 // Calculate number of capture registers (number_of_captures + 1) * 2.
2489 __ leal(rdx, Operand(rax, rax, times_1, 2)); 2483 __ leal(rdx, Operand(rax, rax, times_1, 2));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2530 times_pointer_size, 2524 times_pointer_size,
2531 RegExpImpl::kFirstCaptureOffset), 2525 RegExpImpl::kFirstCaptureOffset),
2532 rdi); 2526 rdi);
2533 __ jmp(&next_capture); 2527 __ jmp(&next_capture);
2534 __ bind(&done); 2528 __ bind(&done);
2535 2529
2536 // Return last match info. 2530 // Return last match info.
2537 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); 2531 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
2538 __ ret(4 * kPointerSize); 2532 __ ret(4 * kPointerSize);
2539 2533
2534 __ bind(&exception);
2535 // Result must now be exception. If there is no pending exception already a
2536 // stack overflow (on the backtrack stack) was detected in RegExp code but
2537 // haven't created the exception yet. Handle that in the runtime system.
2538 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
2539 ExternalReference pending_exception_address(Top::k_pending_exception_address);
2540 __ movq(rbx, pending_exception_address);
2541 __ movq(rax, Operand(rbx, 0));
2542 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
2543 __ cmpq(rax, rdx);
2544 __ j(equal, &runtime);
2545 __ movq(Operand(rbx, 0), rdx);
2546
2547 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
2548 NearLabel termination_exception;
2549 __ j(equal, &termination_exception);
2550 __ Throw(rax);
2551
2552 __ bind(&termination_exception);
2553 __ ThrowUncatchable(TERMINATION, rax);
2554
2540 // Do the runtime call to execute the regexp. 2555 // Do the runtime call to execute the regexp.
2541 __ bind(&runtime); 2556 __ bind(&runtime);
2542 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 2557 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
2543 #endif // V8_INTERPRETED_REGEXP 2558 #endif // V8_INTERPRETED_REGEXP
2544 } 2559 }
2545 2560
2546 2561
2547 void RegExpConstructResultStub::Generate(MacroAssembler* masm) { 2562 void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
2548 const int kMaxInlineLength = 100; 2563 const int kMaxInlineLength = 100;
2549 Label slowcase; 2564 Label slowcase;
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi); 3093 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
3079 __ Set(rax, argc_); 3094 __ Set(rax, argc_);
3080 __ Set(rbx, 0); 3095 __ Set(rbx, 0);
3081 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); 3096 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
3082 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); 3097 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
3083 __ Jump(adaptor, RelocInfo::CODE_TARGET); 3098 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3084 } 3099 }
3085 3100
3086 3101
3087 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { 3102 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
3088 // Check that stack should contain next handler, frame pointer, state and 3103 // Throw exception in eax.
3089 // return address in that order. 3104 __ Throw(rax);
3090 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
3091 StackHandlerConstants::kStateOffset);
3092 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
3093 StackHandlerConstants::kPCOffset);
3094
3095 ExternalReference handler_address(Top::k_handler_address);
3096 __ movq(kScratchRegister, handler_address);
3097 __ movq(rsp, Operand(kScratchRegister, 0));
3098 // get next in chain
3099 __ pop(rcx);
3100 __ movq(Operand(kScratchRegister, 0), rcx);
3101 __ pop(rbp); // pop frame pointer
3102 __ pop(rdx); // remove state
3103
3104 // Before returning we restore the context from the frame pointer if not NULL.
3105 // The frame pointer is NULL in the exception handler of a JS entry frame.
3106 __ Set(rsi, 0); // Tentatively set context pointer to NULL
3107 NearLabel skip;
3108 __ cmpq(rbp, Immediate(0));
3109 __ j(equal, &skip);
3110 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3111 __ bind(&skip);
3112 __ ret(0);
3113 } 3105 }
3114 3106
3115 3107
3116 void CEntryStub::GenerateCore(MacroAssembler* masm, 3108 void CEntryStub::GenerateCore(MacroAssembler* masm,
3117 Label* throw_normal_exception, 3109 Label* throw_normal_exception,
3118 Label* throw_termination_exception, 3110 Label* throw_termination_exception,
3119 Label* throw_out_of_memory_exception, 3111 Label* throw_out_of_memory_exception,
3120 bool do_gc, 3112 bool do_gc,
3121 bool always_allocate_scope) { 3113 bool always_allocate_scope) {
3122 // rax: result parameter for PerformGC, if any. 3114 // rax: result parameter for PerformGC, if any.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
3244 // Handle normal exception. 3236 // Handle normal exception.
3245 __ jmp(throw_normal_exception); 3237 __ jmp(throw_normal_exception);
3246 3238
3247 // Retry. 3239 // Retry.
3248 __ bind(&retry); 3240 __ bind(&retry);
3249 } 3241 }
3250 3242
3251 3243
3252 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, 3244 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
3253 UncatchableExceptionType type) { 3245 UncatchableExceptionType type) {
3254 // Fetch top stack handler. 3246 __ ThrowUncatchable(type, rax);
3255 ExternalReference handler_address(Top::k_handler_address);
3256 __ movq(kScratchRegister, handler_address);
3257 __ movq(rsp, Operand(kScratchRegister, 0));
3258
3259 // Unwind the handlers until the ENTRY handler is found.
3260 NearLabel loop, done;
3261 __ bind(&loop);
3262 // Load the type of the current stack handler.
3263 const int kStateOffset = StackHandlerConstants::kStateOffset;
3264 __ cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY));
3265 __ j(equal, &done);
3266 // Fetch the next handler in the list.
3267 const int kNextOffset = StackHandlerConstants::kNextOffset;
3268 __ movq(rsp, Operand(rsp, kNextOffset));
3269 __ jmp(&loop);
3270 __ bind(&done);
3271
3272 // Set the top handler address to next handler past the current ENTRY handler.
3273 __ movq(kScratchRegister, handler_address);
3274 __ pop(Operand(kScratchRegister, 0));
3275
3276 if (type == OUT_OF_MEMORY) {
3277 // Set external caught exception to false.
3278 ExternalReference external_caught(Top::k_external_caught_exception_address);
3279 __ movq(rax, Immediate(false));
3280 __ store_rax(external_caught);
3281
3282 // Set pending exception and rax to out of memory exception.
3283 ExternalReference pending_exception(Top::k_pending_exception_address);
3284 __ movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
3285 __ store_rax(pending_exception);
3286 }
3287
3288 // Clear the context pointer.
3289 __ Set(rsi, 0);
3290
3291 // Restore registers from handler.
3292 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize ==
3293 StackHandlerConstants::kFPOffset);
3294 __ pop(rbp); // FP
3295 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
3296 StackHandlerConstants::kStateOffset);
3297 __ pop(rdx); // State
3298
3299 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
3300 StackHandlerConstants::kPCOffset);
3301 __ ret(0);
3302 } 3247 }
3303 3248
3304 3249
3305 void CEntryStub::Generate(MacroAssembler* masm) { 3250 void CEntryStub::Generate(MacroAssembler* masm) {
3306 // rax: number of arguments including receiver 3251 // rax: number of arguments including receiver
3307 // rbx: pointer to C function (C callee-saved) 3252 // rbx: pointer to C function (C callee-saved)
3308 // rbp: frame pointer of calling JS frame (restored after C call) 3253 // rbp: frame pointer of calling JS frame (restored after C call)
3309 // rsp: stack pointer (restored after C call) 3254 // rsp: stack pointer (restored after C call)
3310 // rsi: current context (restored) 3255 // rsi: current context (restored)
3311 3256
(...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after
4781 __ Integer32ToSmi(result, result); 4726 __ Integer32ToSmi(result, result);
4782 __ ret(0); 4727 __ ret(0);
4783 } 4728 }
4784 4729
4785 4730
4786 #undef __ 4731 #undef __
4787 4732
4788 } } // namespace v8::internal 4733 } } // namespace v8::internal
4789 4734
4790 #endif // V8_TARGET_ARCH_X64 4735 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/macro-assembler.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698