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

Side by Side Diff: src/full-codegen/arm64/full-codegen-arm64.cc

Issue 1709693002: Revert of [fullcodegen] Remove the hacky %_FastOneByteArrayJoin intrinsic. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 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
« no previous file with comments | « src/full-codegen/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 3225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3236 ZoneList<Expression*>* args = expr->arguments(); 3236 ZoneList<Expression*>* args = expr->arguments();
3237 DCHECK_EQ(1, args->length()); 3237 DCHECK_EQ(1, args->length());
3238 VisitForAccumulatorValue(args->at(0)); 3238 VisitForAccumulatorValue(args->at(0));
3239 __ AssertFunction(x0); 3239 __ AssertFunction(x0);
3240 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset)); 3240 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset));
3241 __ Ldr(x0, FieldMemOperand(x0, Map::kPrototypeOffset)); 3241 __ Ldr(x0, FieldMemOperand(x0, Map::kPrototypeOffset));
3242 context()->Plug(x0); 3242 context()->Plug(x0);
3243 } 3243 }
3244 3244
3245 3245
3246 void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) {
3247 ASM_LOCATION("FullCodeGenerator::EmitFastOneByteArrayJoin");
3248
3249 ZoneList<Expression*>* args = expr->arguments();
3250 DCHECK(args->length() == 2);
3251 VisitForStackValue(args->at(1));
3252 VisitForAccumulatorValue(args->at(0));
3253
3254 Register array = x0;
3255 Register result = x0;
3256 Register elements = x1;
3257 Register element = x2;
3258 Register separator = x3;
3259 Register array_length = x4;
3260 Register result_pos = x5;
3261 Register map = x6;
3262 Register string_length = x10;
3263 Register elements_end = x11;
3264 Register string = x12;
3265 Register scratch1 = x13;
3266 Register scratch2 = x14;
3267 Register scratch3 = x7;
3268 Register separator_length = x15;
3269
3270 Label bailout, done, one_char_separator, long_separator,
3271 non_trivial_array, not_size_one_array, loop,
3272 empty_separator_loop, one_char_separator_loop,
3273 one_char_separator_loop_entry, long_separator_loop;
3274
3275 // The separator operand is on the stack.
3276 __ Pop(separator);
3277
3278 // Check that the array is a JSArray.
3279 __ JumpIfSmi(array, &bailout);
3280 __ JumpIfNotObjectType(array, map, scratch1, JS_ARRAY_TYPE, &bailout);
3281
3282 // Check that the array has fast elements.
3283 __ CheckFastElements(map, scratch1, &bailout);
3284
3285 // If the array has length zero, return the empty string.
3286 // Load and untag the length of the array.
3287 // It is an unsigned value, so we can skip sign extension.
3288 // We assume little endianness.
3289 __ Ldrsw(array_length,
3290 UntagSmiFieldMemOperand(array, JSArray::kLengthOffset));
3291 __ Cbnz(array_length, &non_trivial_array);
3292 __ LoadRoot(result, Heap::kempty_stringRootIndex);
3293 __ B(&done);
3294
3295 __ Bind(&non_trivial_array);
3296 // Get the FixedArray containing array's elements.
3297 __ Ldr(elements, FieldMemOperand(array, JSArray::kElementsOffset));
3298
3299 // Check that all array elements are sequential one-byte strings, and
3300 // accumulate the sum of their lengths.
3301 __ Mov(string_length, 0);
3302 __ Add(element, elements, FixedArray::kHeaderSize - kHeapObjectTag);
3303 __ Add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
3304 // Loop condition: while (element < elements_end).
3305 // Live values in registers:
3306 // elements: Fixed array of strings.
3307 // array_length: Length of the fixed array of strings (not smi)
3308 // separator: Separator string
3309 // string_length: Accumulated sum of string lengths (not smi).
3310 // element: Current array element.
3311 // elements_end: Array end.
3312 if (FLAG_debug_code) {
3313 __ Cmp(array_length, 0);
3314 __ Assert(gt, kNoEmptyArraysHereInEmitFastOneByteArrayJoin);
3315 }
3316 __ Bind(&loop);
3317 __ Ldr(string, MemOperand(element, kPointerSize, PostIndex));
3318 __ JumpIfSmi(string, &bailout);
3319 __ Ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset));
3320 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
3321 __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
3322 __ Ldrsw(scratch1,
3323 UntagSmiFieldMemOperand(string, SeqOneByteString::kLengthOffset));
3324 __ Adds(string_length, string_length, scratch1);
3325 __ B(vs, &bailout);
3326 __ Cmp(element, elements_end);
3327 __ B(lt, &loop);
3328
3329 // If array_length is 1, return elements[0], a string.
3330 __ Cmp(array_length, 1);
3331 __ B(ne, &not_size_one_array);
3332 __ Ldr(result, FieldMemOperand(elements, FixedArray::kHeaderSize));
3333 __ B(&done);
3334
3335 __ Bind(&not_size_one_array);
3336
3337 // Live values in registers:
3338 // separator: Separator string
3339 // array_length: Length of the array (not smi).
3340 // string_length: Sum of string lengths (not smi).
3341 // elements: FixedArray of strings.
3342
3343 // Check that the separator is a flat one-byte string.
3344 __ JumpIfSmi(separator, &bailout);
3345 __ Ldr(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset));
3346 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
3347 __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
3348
3349 // Add (separator length times array_length) - separator length to the
3350 // string_length to get the length of the result string.
3351 // Load the separator length as untagged.
3352 // We assume little endianness, and that the length is positive.
3353 __ Ldrsw(separator_length,
3354 UntagSmiFieldMemOperand(separator,
3355 SeqOneByteString::kLengthOffset));
3356 __ Sub(string_length, string_length, separator_length);
3357 __ Umaddl(string_length, array_length.W(), separator_length.W(),
3358 string_length);
3359
3360 // Bailout for large object allocations.
3361 __ Cmp(string_length, Page::kMaxRegularHeapObjectSize);
3362 __ B(gt, &bailout);
3363
3364 // Get first element in the array.
3365 __ Add(element, elements, FixedArray::kHeaderSize - kHeapObjectTag);
3366 // Live values in registers:
3367 // element: First array element
3368 // separator: Separator string
3369 // string_length: Length of result string (not smi)
3370 // array_length: Length of the array (not smi).
3371 __ AllocateOneByteString(result, string_length, scratch1, scratch2, scratch3,
3372 &bailout);
3373
3374 // Prepare for looping. Set up elements_end to end of the array. Set
3375 // result_pos to the position of the result where to write the first
3376 // character.
3377 // TODO(all): useless unless AllocateOneByteString trashes the register.
3378 __ Add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
3379 __ Add(result_pos, result, SeqOneByteString::kHeaderSize - kHeapObjectTag);
3380
3381 // Check the length of the separator.
3382 __ Cmp(separator_length, 1);
3383 __ B(eq, &one_char_separator);
3384 __ B(gt, &long_separator);
3385
3386 // Empty separator case
3387 __ Bind(&empty_separator_loop);
3388 // Live values in registers:
3389 // result_pos: the position to which we are currently copying characters.
3390 // element: Current array element.
3391 // elements_end: Array end.
3392
3393 // Copy next array element to the result.
3394 __ Ldr(string, MemOperand(element, kPointerSize, PostIndex));
3395 __ Ldrsw(string_length,
3396 UntagSmiFieldMemOperand(string, String::kLengthOffset));
3397 __ Add(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
3398 __ CopyBytes(result_pos, string, string_length, scratch1);
3399 __ Cmp(element, elements_end);
3400 __ B(lt, &empty_separator_loop); // End while (element < elements_end).
3401 __ B(&done);
3402
3403 // One-character separator case
3404 __ Bind(&one_char_separator);
3405 // Replace separator with its one-byte character value.
3406 __ Ldrb(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
3407 // Jump into the loop after the code that copies the separator, so the first
3408 // element is not preceded by a separator
3409 __ B(&one_char_separator_loop_entry);
3410
3411 __ Bind(&one_char_separator_loop);
3412 // Live values in registers:
3413 // result_pos: the position to which we are currently copying characters.
3414 // element: Current array element.
3415 // elements_end: Array end.
3416 // separator: Single separator one-byte char (in lower byte).
3417
3418 // Copy the separator character to the result.
3419 __ Strb(separator, MemOperand(result_pos, 1, PostIndex));
3420
3421 // Copy next array element to the result.
3422 __ Bind(&one_char_separator_loop_entry);
3423 __ Ldr(string, MemOperand(element, kPointerSize, PostIndex));
3424 __ Ldrsw(string_length,
3425 UntagSmiFieldMemOperand(string, String::kLengthOffset));
3426 __ Add(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
3427 __ CopyBytes(result_pos, string, string_length, scratch1);
3428 __ Cmp(element, elements_end);
3429 __ B(lt, &one_char_separator_loop); // End while (element < elements_end).
3430 __ B(&done);
3431
3432 // Long separator case (separator is more than one character). Entry is at the
3433 // label long_separator below.
3434 __ Bind(&long_separator_loop);
3435 // Live values in registers:
3436 // result_pos: the position to which we are currently copying characters.
3437 // element: Current array element.
3438 // elements_end: Array end.
3439 // separator: Separator string.
3440
3441 // Copy the separator to the result.
3442 // TODO(all): hoist next two instructions.
3443 __ Ldrsw(string_length,
3444 UntagSmiFieldMemOperand(separator, String::kLengthOffset));
3445 __ Add(string, separator, SeqOneByteString::kHeaderSize - kHeapObjectTag);
3446 __ CopyBytes(result_pos, string, string_length, scratch1);
3447
3448 __ Bind(&long_separator);
3449 __ Ldr(string, MemOperand(element, kPointerSize, PostIndex));
3450 __ Ldrsw(string_length,
3451 UntagSmiFieldMemOperand(string, String::kLengthOffset));
3452 __ Add(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
3453 __ CopyBytes(result_pos, string, string_length, scratch1);
3454 __ Cmp(element, elements_end);
3455 __ B(lt, &long_separator_loop); // End while (element < elements_end).
3456 __ B(&done);
3457
3458 __ Bind(&bailout);
3459 // Returning undefined will force slower code to handle it.
3460 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
3461 __ Bind(&done);
3462 context()->Plug(result);
3463 }
3464
3465
3246 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { 3466 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
3247 DCHECK(expr->arguments()->length() == 0); 3467 DCHECK(expr->arguments()->length() == 0);
3248 ExternalReference debug_is_active = 3468 ExternalReference debug_is_active =
3249 ExternalReference::debug_is_active_address(isolate()); 3469 ExternalReference::debug_is_active_address(isolate());
3250 __ Mov(x10, debug_is_active); 3470 __ Mov(x10, debug_is_active);
3251 __ Ldrb(x0, MemOperand(x10)); 3471 __ Ldrb(x0, MemOperand(x10));
3252 __ SmiTag(x0); 3472 __ SmiTag(x0);
3253 context()->Plug(x0); 3473 context()->Plug(x0);
3254 } 3474 }
3255 3475
(...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after
4341 } 4561 }
4342 4562
4343 return INTERRUPT; 4563 return INTERRUPT;
4344 } 4564 }
4345 4565
4346 4566
4347 } // namespace internal 4567 } // namespace internal
4348 } // namespace v8 4568 } // namespace v8
4349 4569
4350 #endif // V8_TARGET_ARCH_ARM64 4570 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/full-codegen/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698