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

Side by Side Diff: src/ia32/lithium-codegen-ia32.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/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.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 2408 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 // Subtracting from length accounts for one of them add one more. 2419 // Subtracting from length accounts for one of them add one more.
2420 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); 2420 __ mov(result, Operand(arguments, length, times_4, kPointerSize));
2421 } 2421 }
2422 2422
2423 2423
2424 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2424 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2425 Register result = ToRegister(instr->result()); 2425 Register result = ToRegister(instr->result());
2426 2426
2427 // Load the result. 2427 // Load the result.
2428 __ mov(result, 2428 __ mov(result,
2429 BuildFastArrayOperand(instr->elements(), instr->key(), 2429 BuildFastArrayOperand(instr->elements(),
2430 instr->key(),
2430 FAST_ELEMENTS, 2431 FAST_ELEMENTS,
2431 FixedArray::kHeaderSize - kHeapObjectTag)); 2432 FixedArray::kHeaderSize - kHeapObjectTag,
2433 instr->additional_index()));
2432 2434
2433 // Check for the hole value. 2435 // Check for the hole value.
2434 if (instr->hydrogen()->RequiresHoleCheck()) { 2436 if (instr->hydrogen()->RequiresHoleCheck()) {
2435 __ cmp(result, factory()->the_hole_value()); 2437 __ cmp(result, factory()->the_hole_value());
2436 DeoptimizeIf(equal, instr->environment()); 2438 DeoptimizeIf(equal, instr->environment());
2437 } 2439 }
2438 } 2440 }
2439 2441
2440 2442
2441 void LCodeGen::DoLoadKeyedFastDoubleElement( 2443 void LCodeGen::DoLoadKeyedFastDoubleElement(
2442 LLoadKeyedFastDoubleElement* instr) { 2444 LLoadKeyedFastDoubleElement* instr) {
2443 XMMRegister result = ToDoubleRegister(instr->result()); 2445 XMMRegister result = ToDoubleRegister(instr->result());
2444 2446
2445 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2447 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2446 sizeof(kHoleNanLower32); 2448 sizeof(kHoleNanLower32);
2447 Operand hole_check_operand = BuildFastArrayOperand( 2449 Operand hole_check_operand = BuildFastArrayOperand(
2448 instr->elements(), instr->key(), 2450 instr->elements(), instr->key(),
2449 FAST_DOUBLE_ELEMENTS, 2451 FAST_DOUBLE_ELEMENTS,
2450 offset); 2452 offset,
2453 instr->additional_index());
2451 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); 2454 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2452 DeoptimizeIf(equal, instr->environment()); 2455 DeoptimizeIf(equal, instr->environment());
2453 2456
2454 Operand double_load_operand = BuildFastArrayOperand( 2457 Operand double_load_operand = BuildFastArrayOperand(
2455 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, 2458 instr->elements(),
2456 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 2459 instr->key(),
2460 FAST_DOUBLE_ELEMENTS,
2461 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2462 instr->additional_index());
2457 __ movdbl(result, double_load_operand); 2463 __ movdbl(result, double_load_operand);
2458 } 2464 }
2459 2465
2460 2466
2461 Operand LCodeGen::BuildFastArrayOperand( 2467 Operand LCodeGen::BuildFastArrayOperand(
2462 LOperand* elements_pointer, 2468 LOperand* elements_pointer,
2463 LOperand* key, 2469 LOperand* key,
2464 ElementsKind elements_kind, 2470 ElementsKind elements_kind,
2465 uint32_t offset) { 2471 uint32_t offset,
2472 uint32_t additional_index) {
2466 Register elements_pointer_reg = ToRegister(elements_pointer); 2473 Register elements_pointer_reg = ToRegister(elements_pointer);
2467 int shift_size = ElementsKindToShiftSize(elements_kind); 2474 int shift_size = ElementsKindToShiftSize(elements_kind);
2468 if (key->IsConstantOperand()) { 2475 if (key->IsConstantOperand()) {
2469 int constant_value = ToInteger32(LConstantOperand::cast(key)); 2476 int constant_value = ToInteger32(LConstantOperand::cast(key));
2470 if (constant_value & 0xF0000000) { 2477 if (constant_value & 0xF0000000) {
2471 Abort("array index constant value too big"); 2478 Abort("array index constant value too big");
2472 } 2479 }
2473 return Operand(elements_pointer_reg, 2480 return Operand(elements_pointer_reg,
2474 constant_value * (1 << shift_size) + offset); 2481 ((constant_value + additional_index) << shift_size)
2482 + offset);
2475 } else { 2483 } else {
2476 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 2484 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2477 return Operand(elements_pointer_reg, ToRegister(key), scale_factor, offset); 2485 return Operand(elements_pointer_reg,
2486 ToRegister(key),
2487 scale_factor,
2488 offset + (additional_index << shift_size));
2478 } 2489 }
2479 } 2490 }
2480 2491
2481 2492
2482 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2493 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2483 LLoadKeyedSpecializedArrayElement* instr) { 2494 LLoadKeyedSpecializedArrayElement* instr) {
2484 ElementsKind elements_kind = instr->elements_kind(); 2495 ElementsKind elements_kind = instr->elements_kind();
2485 Operand operand(BuildFastArrayOperand(instr->external_pointer(), 2496 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
2486 instr->key(), elements_kind, 0)); 2497 instr->key(),
2498 elements_kind,
2499 0,
2500 instr->additional_index()));
2487 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 2501 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2488 XMMRegister result(ToDoubleRegister(instr->result())); 2502 XMMRegister result(ToDoubleRegister(instr->result()));
2489 __ movss(result, operand); 2503 __ movss(result, operand);
2490 __ cvtss2sd(result, result); 2504 __ cvtss2sd(result, result);
2491 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 2505 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2492 __ movdbl(ToDoubleRegister(instr->result()), operand); 2506 __ movdbl(ToDoubleRegister(instr->result()), operand);
2493 } else { 2507 } else {
2494 Register result(ToRegister(instr->result())); 2508 Register result(ToRegister(instr->result()));
2495 switch (elements_kind) { 2509 switch (elements_kind) {
2496 case EXTERNAL_BYTE_ELEMENTS: 2510 case EXTERNAL_BYTE_ELEMENTS:
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
3413 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 3427 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
3414 DeoptimizeIf(above_equal, instr->environment()); 3428 DeoptimizeIf(above_equal, instr->environment());
3415 } 3429 }
3416 } 3430 }
3417 3431
3418 3432
3419 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3433 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3420 LStoreKeyedSpecializedArrayElement* instr) { 3434 LStoreKeyedSpecializedArrayElement* instr) {
3421 ElementsKind elements_kind = instr->elements_kind(); 3435 ElementsKind elements_kind = instr->elements_kind();
3422 Operand operand(BuildFastArrayOperand(instr->external_pointer(), 3436 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
3423 instr->key(), elements_kind, 0)); 3437 instr->key(),
3438 elements_kind,
3439 0,
3440 instr->additional_index()));
3424 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3441 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3425 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 3442 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
3426 __ movss(operand, xmm0); 3443 __ movss(operand, xmm0);
3427 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3444 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3428 __ movdbl(operand, ToDoubleRegister(instr->value())); 3445 __ movdbl(operand, ToDoubleRegister(instr->value()));
3429 } else { 3446 } else {
3430 Register value = ToRegister(instr->value()); 3447 Register value = ToRegister(instr->value());
3431 switch (elements_kind) { 3448 switch (elements_kind) {
3432 case EXTERNAL_PIXEL_ELEMENTS: 3449 case EXTERNAL_PIXEL_ELEMENTS:
3433 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3450 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
(...skipping 20 matching lines...) Expand all
3454 } 3471 }
3455 } 3472 }
3456 } 3473 }
3457 3474
3458 3475
3459 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3476 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
3460 Register value = ToRegister(instr->value()); 3477 Register value = ToRegister(instr->value());
3461 Register elements = ToRegister(instr->object()); 3478 Register elements = ToRegister(instr->object());
3462 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3479 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3463 3480
3464 // Do the store. 3481 Operand operand = BuildFastArrayOperand(
3465 if (instr->key()->IsConstantOperand()) { 3482 instr->object(),
3466 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 3483 instr->key(),
3467 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3484 FAST_ELEMENTS,
3468 int offset = 3485 FixedArray::kHeaderSize - kHeapObjectTag,
3469 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 3486 instr->additional_index());
3470 __ mov(FieldOperand(elements, offset), value); 3487 __ mov(operand, value);
3471 } else {
3472 __ mov(FieldOperand(elements,
3473 key,
3474 times_pointer_size,
3475 FixedArray::kHeaderSize),
3476 value);
3477 }
3478 3488
3479 if (instr->hydrogen()->NeedsWriteBarrier()) { 3489 if (instr->hydrogen()->NeedsWriteBarrier()) {
3490 ASSERT(!instr->key()->IsConstantOperand());
3480 HType type = instr->hydrogen()->value()->type(); 3491 HType type = instr->hydrogen()->value()->type();
3481 SmiCheck check_needed = 3492 SmiCheck check_needed =
3482 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3493 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3483 // Compute address of modified element and store it into key register. 3494 // Compute address of modified element and store it into key register.
3484 __ lea(key, 3495 __ lea(key, operand);
3485 FieldOperand(elements,
3486 key,
3487 times_pointer_size,
3488 FixedArray::kHeaderSize));
3489 __ RecordWrite(elements, 3496 __ RecordWrite(elements,
3490 key, 3497 key,
3491 value, 3498 value,
3492 kSaveFPRegs, 3499 kSaveFPRegs,
3493 EMIT_REMEMBERED_SET, 3500 EMIT_REMEMBERED_SET,
3494 check_needed); 3501 check_needed);
3495 } 3502 }
3496 } 3503 }
3497 3504
3498 3505
3499 void LCodeGen::DoStoreKeyedFastDoubleElement( 3506 void LCodeGen::DoStoreKeyedFastDoubleElement(
3500 LStoreKeyedFastDoubleElement* instr) { 3507 LStoreKeyedFastDoubleElement* instr) {
3501 XMMRegister value = ToDoubleRegister(instr->value()); 3508 XMMRegister value = ToDoubleRegister(instr->value());
3502 3509
3503 if (instr->NeedsCanonicalization()) { 3510 if (instr->NeedsCanonicalization()) {
3504 Label have_value; 3511 Label have_value;
3505 3512
3506 __ ucomisd(value, value); 3513 __ ucomisd(value, value);
3507 __ j(parity_odd, &have_value); // NaN. 3514 __ j(parity_odd, &have_value); // NaN.
3508 3515
3509 ExternalReference canonical_nan_reference = 3516 ExternalReference canonical_nan_reference =
3510 ExternalReference::address_of_canonical_non_hole_nan(); 3517 ExternalReference::address_of_canonical_non_hole_nan();
3511 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); 3518 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
3512 __ bind(&have_value); 3519 __ bind(&have_value);
3513 } 3520 }
3514 3521
3515 Operand double_store_operand = BuildFastArrayOperand( 3522 Operand double_store_operand = BuildFastArrayOperand(
3516 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, 3523 instr->elements(),
3517 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 3524 instr->key(),
3525 FAST_DOUBLE_ELEMENTS,
3526 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3527 instr->additional_index());
3518 __ movdbl(double_store_operand, value); 3528 __ movdbl(double_store_operand, value);
3519 } 3529 }
3520 3530
3521 3531
3522 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3532 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3523 ASSERT(ToRegister(instr->context()).is(esi)); 3533 ASSERT(ToRegister(instr->context()).is(esi));
3524 ASSERT(ToRegister(instr->object()).is(edx)); 3534 ASSERT(ToRegister(instr->object()).is(edx));
3525 ASSERT(ToRegister(instr->key()).is(ecx)); 3535 ASSERT(ToRegister(instr->key()).is(ecx));
3526 ASSERT(ToRegister(instr->value()).is(eax)); 3536 ASSERT(ToRegister(instr->value()).is(eax));
3527 3537
(...skipping 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after
5062 FixedArray::kHeaderSize - kPointerSize)); 5072 FixedArray::kHeaderSize - kPointerSize));
5063 __ bind(&done); 5073 __ bind(&done);
5064 } 5074 }
5065 5075
5066 5076
5067 #undef __ 5077 #undef __
5068 5078
5069 } } // namespace v8::internal 5079 } } // namespace v8::internal
5070 5080
5071 #endif // V8_TARGET_ARCH_IA32 5081 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698