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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 10382055: Array index computation dehoisting. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed review comments. Created 8 years, 7 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/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-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 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 2357 matching lines...) Expand 10 before | Expand all | Expand 10 after
2368 2368
2369 // There are two words between the frame pointer and the last argument. 2369 // There are two words between the frame pointer and the last argument.
2370 // Subtracting from length accounts for one of them add one more. 2370 // Subtracting from length accounts for one of them add one more.
2371 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); 2371 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
2372 } 2372 }
2373 2373
2374 2374
2375 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2375 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2376 Register result = ToRegister(instr->result()); 2376 Register result = ToRegister(instr->result());
2377 2377
2378 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
2379 // Sign extend key because it could be a 32 bit negative value
2380 // and the dehoisted address computation happens in 64 bits.
2381 Register key_reg = ToRegister(instr->key());
2382 __ movsxlq(key_reg, key_reg);
2383 }
2384
2378 // Load the result. 2385 // Load the result.
2379 __ movq(result, 2386 __ movq(result,
2380 BuildFastArrayOperand(instr->elements(), instr->key(), 2387 BuildFastArrayOperand(instr->elements(),
2388 instr->key(),
2381 FAST_ELEMENTS, 2389 FAST_ELEMENTS,
2382 FixedArray::kHeaderSize - kHeapObjectTag)); 2390 FixedArray::kHeaderSize - kHeapObjectTag,
2391 instr->additional_index()));
2383 2392
2384 // Check for the hole value. 2393 // Check for the hole value.
2385 if (instr->hydrogen()->RequiresHoleCheck()) { 2394 if (instr->hydrogen()->RequiresHoleCheck()) {
2386 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 2395 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
2387 DeoptimizeIf(equal, instr->environment()); 2396 DeoptimizeIf(equal, instr->environment());
2388 } 2397 }
2389 } 2398 }
2390 2399
2391 2400
2392 void LCodeGen::DoLoadKeyedFastDoubleElement( 2401 void LCodeGen::DoLoadKeyedFastDoubleElement(
2393 LLoadKeyedFastDoubleElement* instr) { 2402 LLoadKeyedFastDoubleElement* instr) {
2394 XMMRegister result(ToDoubleRegister(instr->result())); 2403 XMMRegister result(ToDoubleRegister(instr->result()));
2395 2404
2405 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
2406 // Sign extend key because it could be a 32 bit negative value
2407 // and the dehoisted address computation happens in 64 bits
2408 Register key_reg = ToRegister(instr->key());
2409 __ movsxlq(key_reg, key_reg);
2410 }
2411
2396 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2412 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2397 sizeof(kHoleNanLower32); 2413 sizeof(kHoleNanLower32);
2398 Operand hole_check_operand = BuildFastArrayOperand( 2414 Operand hole_check_operand = BuildFastArrayOperand(
2399 instr->elements(), 2415 instr->elements(),
2400 instr->key(), 2416 instr->key(),
2401 FAST_DOUBLE_ELEMENTS, 2417 FAST_DOUBLE_ELEMENTS,
2402 offset); 2418 offset,
2419 instr->additional_index());
2403 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 2420 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2404 DeoptimizeIf(equal, instr->environment()); 2421 DeoptimizeIf(equal, instr->environment());
2405 2422
2406 Operand double_load_operand = BuildFastArrayOperand( 2423 Operand double_load_operand = BuildFastArrayOperand(
2407 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, 2424 instr->elements(),
2408 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 2425 instr->key(),
2426 FAST_DOUBLE_ELEMENTS,
2427 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2428 instr->additional_index());
2409 __ movsd(result, double_load_operand); 2429 __ movsd(result, double_load_operand);
2410 } 2430 }
2411 2431
2412 2432
2413 Operand LCodeGen::BuildFastArrayOperand( 2433 Operand LCodeGen::BuildFastArrayOperand(
2414 LOperand* elements_pointer, 2434 LOperand* elements_pointer,
2415 LOperand* key, 2435 LOperand* key,
2416 ElementsKind elements_kind, 2436 ElementsKind elements_kind,
2417 uint32_t offset) { 2437 uint32_t offset,
2438 uint32_t additional_index) {
2418 Register elements_pointer_reg = ToRegister(elements_pointer); 2439 Register elements_pointer_reg = ToRegister(elements_pointer);
2419 int shift_size = ElementsKindToShiftSize(elements_kind); 2440 int shift_size = ElementsKindToShiftSize(elements_kind);
2420 if (key->IsConstantOperand()) { 2441 if (key->IsConstantOperand()) {
2421 int constant_value = ToInteger32(LConstantOperand::cast(key)); 2442 int constant_value = ToInteger32(LConstantOperand::cast(key));
2422 if (constant_value & 0xF0000000) { 2443 if (constant_value & 0xF0000000) {
2423 Abort("array index constant value too big"); 2444 Abort("array index constant value too big");
2424 } 2445 }
2425 return Operand(elements_pointer_reg, 2446 return Operand(elements_pointer_reg,
2426 constant_value * (1 << shift_size) + offset); 2447 ((constant_value + additional_index) << shift_size)
2448 + offset);
2427 } else { 2449 } else {
2428 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 2450 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2429 return Operand(elements_pointer_reg, ToRegister(key), 2451 return Operand(elements_pointer_reg,
2430 scale_factor, offset); 2452 ToRegister(key),
2453 scale_factor,
2454 offset + (additional_index << shift_size));
2431 } 2455 }
2432 } 2456 }
2433 2457
2434 2458
2435 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2459 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2436 LLoadKeyedSpecializedArrayElement* instr) { 2460 LLoadKeyedSpecializedArrayElement* instr) {
2437 ElementsKind elements_kind = instr->elements_kind(); 2461 ElementsKind elements_kind = instr->elements_kind();
2438 Operand operand(BuildFastArrayOperand(instr->external_pointer(), 2462 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
2439 instr->key(), elements_kind, 0)); 2463 instr->key(),
2464 elements_kind,
2465 0,
2466 instr->additional_index()));
2467 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
2468 // Sign extend key because it could be a 32 bit negative value
2469 // and the dehoisted address computation happens in 64 bits
2470 Register key_reg = ToRegister(instr->key());
2471 __ movsxlq(key_reg, key_reg);
2472 }
2473
2440 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 2474 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2441 XMMRegister result(ToDoubleRegister(instr->result())); 2475 XMMRegister result(ToDoubleRegister(instr->result()));
2442 __ movss(result, operand); 2476 __ movss(result, operand);
2443 __ cvtss2sd(result, result); 2477 __ cvtss2sd(result, result);
2444 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 2478 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2445 __ movsd(ToDoubleRegister(instr->result()), operand); 2479 __ movsd(ToDoubleRegister(instr->result()), operand);
2446 } else { 2480 } else {
2447 Register result(ToRegister(instr->result())); 2481 Register result(ToRegister(instr->result()));
2448 switch (elements_kind) { 2482 switch (elements_kind) {
2449 case EXTERNAL_BYTE_ELEMENTS: 2483 case EXTERNAL_BYTE_ELEMENTS:
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after
3331 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3365 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3332 : isolate()->builtins()->StoreIC_Initialize(); 3366 : isolate()->builtins()->StoreIC_Initialize();
3333 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3367 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3334 } 3368 }
3335 3369
3336 3370
3337 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3371 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3338 LStoreKeyedSpecializedArrayElement* instr) { 3372 LStoreKeyedSpecializedArrayElement* instr) {
3339 ElementsKind elements_kind = instr->elements_kind(); 3373 ElementsKind elements_kind = instr->elements_kind();
3340 Operand operand(BuildFastArrayOperand(instr->external_pointer(), 3374 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
3341 instr->key(), elements_kind, 0)); 3375 instr->key(),
3376 elements_kind,
3377 0,
3378 instr->additional_index()));
3379
3380 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
3381 // Sign extend key because it could be a 32 bit negative value
3382 // and the dehoisted address computation happens in 64 bits
3383 Register key_reg = ToRegister(instr->key());
3384 __ movsxlq(key_reg, key_reg);
3385 }
3386
3342 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3387 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3343 XMMRegister value(ToDoubleRegister(instr->value())); 3388 XMMRegister value(ToDoubleRegister(instr->value()));
3344 __ cvtsd2ss(value, value); 3389 __ cvtsd2ss(value, value);
3345 __ movss(operand, value); 3390 __ movss(operand, value);
3346 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3391 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3347 __ movsd(operand, ToDoubleRegister(instr->value())); 3392 __ movsd(operand, ToDoubleRegister(instr->value()));
3348 } else { 3393 } else {
3349 Register value(ToRegister(instr->value())); 3394 Register value(ToRegister(instr->value()));
3350 switch (elements_kind) { 3395 switch (elements_kind) {
3351 case EXTERNAL_PIXEL_ELEMENTS: 3396 case EXTERNAL_PIXEL_ELEMENTS:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3401 } 3446 }
3402 DeoptimizeIf(below_equal, instr->environment()); 3447 DeoptimizeIf(below_equal, instr->environment());
3403 } 3448 }
3404 3449
3405 3450
3406 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3451 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
3407 Register value = ToRegister(instr->value()); 3452 Register value = ToRegister(instr->value());
3408 Register elements = ToRegister(instr->object()); 3453 Register elements = ToRegister(instr->object());
3409 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3454 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3410 3455
3411 // Do the store. 3456 Operand operand =
3412 if (instr->key()->IsConstantOperand()) { 3457 BuildFastArrayOperand(instr->object(),
3413 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 3458 instr->key(),
3414 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3459 FAST_ELEMENTS,
3415 int offset = 3460 FixedArray::kHeaderSize - kHeapObjectTag,
3416 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 3461 instr->additional_index());
3417 __ movq(FieldOperand(elements, offset), value); 3462
3418 } else { 3463 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
3419 __ movq(FieldOperand(elements, 3464 // Sign extend key because it could be a 32 bit negative value
3420 key, 3465 // and the dehoisted address computation happens in 64 bits
3421 times_pointer_size, 3466 Register key_reg = ToRegister(instr->key());
3422 FixedArray::kHeaderSize), 3467 __ movsxlq(key_reg, key_reg);
3423 value);
3424 } 3468 }
3425 3469
3470 __ movq(operand, value);
3471
3426 if (instr->hydrogen()->NeedsWriteBarrier()) { 3472 if (instr->hydrogen()->NeedsWriteBarrier()) {
3473 ASSERT(!instr->key()->IsConstantOperand());
3427 HType type = instr->hydrogen()->value()->type(); 3474 HType type = instr->hydrogen()->value()->type();
3428 SmiCheck check_needed = 3475 SmiCheck check_needed =
3429 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3476 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3430 // Compute address of modified element and store it into key register. 3477 // Compute address of modified element and store it into key register.
3431 __ lea(key, FieldOperand(elements, 3478 __ lea(key, operand);
3432 key,
3433 times_pointer_size,
3434 FixedArray::kHeaderSize));
3435 __ RecordWrite(elements, 3479 __ RecordWrite(elements,
3436 key, 3480 key,
3437 value, 3481 value,
3438 kSaveFPRegs, 3482 kSaveFPRegs,
3439 EMIT_REMEMBERED_SET, 3483 EMIT_REMEMBERED_SET,
3440 check_needed); 3484 check_needed);
3441 } 3485 }
3442 } 3486 }
3443 3487
3444 3488
3445 void LCodeGen::DoStoreKeyedFastDoubleElement( 3489 void LCodeGen::DoStoreKeyedFastDoubleElement(
3446 LStoreKeyedFastDoubleElement* instr) { 3490 LStoreKeyedFastDoubleElement* instr) {
3447 XMMRegister value = ToDoubleRegister(instr->value()); 3491 XMMRegister value = ToDoubleRegister(instr->value());
3448 3492
3449 if (instr->NeedsCanonicalization()) { 3493 if (instr->NeedsCanonicalization()) {
3450 Label have_value; 3494 Label have_value;
3451 3495
3452 __ ucomisd(value, value); 3496 __ ucomisd(value, value);
3453 __ j(parity_odd, &have_value); // NaN. 3497 __ j(parity_odd, &have_value); // NaN.
3454 3498
3455 __ Set(kScratchRegister, BitCast<uint64_t>( 3499 __ Set(kScratchRegister, BitCast<uint64_t>(
3456 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); 3500 FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
3457 __ movq(value, kScratchRegister); 3501 __ movq(value, kScratchRegister);
3458 3502
3459 __ bind(&have_value); 3503 __ bind(&have_value);
3460 } 3504 }
3461 3505
3462 Operand double_store_operand = BuildFastArrayOperand( 3506 Operand double_store_operand = BuildFastArrayOperand(
3463 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, 3507 instr->elements(),
3464 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 3508 instr->key(),
3509 FAST_DOUBLE_ELEMENTS,
3510 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3511 instr->additional_index());
3512
3513 if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
3514 // Sign extend key because it could be a 32 bit negative value
3515 // and the dehoisted address computation happens in 64 bits
3516 Register key_reg = ToRegister(instr->key());
3517 __ movsxlq(key_reg, key_reg);
3518 }
3519
3465 __ movsd(double_store_operand, value); 3520 __ movsd(double_store_operand, value);
3466 } 3521 }
3467 3522
3468 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3523 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3469 ASSERT(ToRegister(instr->object()).is(rdx)); 3524 ASSERT(ToRegister(instr->object()).is(rdx));
3470 ASSERT(ToRegister(instr->key()).is(rcx)); 3525 ASSERT(ToRegister(instr->key()).is(rcx));
3471 ASSERT(ToRegister(instr->value()).is(rax)); 3526 ASSERT(ToRegister(instr->value()).is(rax));
3472 3527
3473 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3528 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3474 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3529 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
(...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after
4817 FixedArray::kHeaderSize - kPointerSize)); 4872 FixedArray::kHeaderSize - kPointerSize));
4818 __ bind(&done); 4873 __ bind(&done);
4819 } 4874 }
4820 4875
4821 4876
4822 #undef __ 4877 #undef __
4823 4878
4824 } } // namespace v8::internal 4879 } } // namespace v8::internal
4825 4880
4826 #endif // V8_TARGET_ARCH_X64 4881 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698