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

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

Issue 10209027: Implement tracking and optimizations of packed arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: New upload 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
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 2365 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 Immediate(factory()->fixed_cow_array_map())); 2376 Immediate(factory()->fixed_cow_array_map()));
2377 __ j(equal, &done, Label::kNear); 2377 __ j(equal, &done, Label::kNear);
2378 Register temp((result.is(eax)) ? ebx : eax); 2378 Register temp((result.is(eax)) ? ebx : eax);
2379 __ push(temp); 2379 __ push(temp);
2380 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); 2380 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
2381 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); 2381 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset));
2382 __ and_(temp, Map::kElementsKindMask); 2382 __ and_(temp, Map::kElementsKindMask);
2383 __ shr(temp, Map::kElementsKindShift); 2383 __ shr(temp, Map::kElementsKindShift);
2384 __ cmp(temp, FAST_ELEMENTS); 2384 __ cmp(temp, FAST_ELEMENTS);
2385 __ j(equal, &ok, Label::kNear); 2385 __ j(equal, &ok, Label::kNear);
2386 __ cmp(temp, FAST_HOLEY_ELEMENTS);
2387 __ j(equal, &ok, Label::kNear);
2386 __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 2388 __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
2387 __ j(less, &fail, Label::kNear); 2389 __ j(less, &fail, Label::kNear);
2388 __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); 2390 __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND);
2389 __ j(less_equal, &ok, Label::kNear); 2391 __ j(less_equal, &ok, Label::kNear);
2390 __ bind(&fail); 2392 __ bind(&fail);
2391 __ Abort("Check for fast or external elements failed."); 2393 __ Abort("Check for fast or external elements failed.");
2392 __ bind(&ok); 2394 __ bind(&ok);
2393 __ pop(temp); 2395 __ pop(temp);
2394 __ bind(&done); 2396 __ bind(&done);
2395 } 2397 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2434 __ cmp(result, factory()->the_hole_value()); 2436 __ cmp(result, factory()->the_hole_value());
2435 DeoptimizeIf(equal, instr->environment()); 2437 DeoptimizeIf(equal, instr->environment());
2436 } 2438 }
2437 } 2439 }
2438 2440
2439 2441
2440 void LCodeGen::DoLoadKeyedFastDoubleElement( 2442 void LCodeGen::DoLoadKeyedFastDoubleElement(
2441 LLoadKeyedFastDoubleElement* instr) { 2443 LLoadKeyedFastDoubleElement* instr) {
2442 XMMRegister result = ToDoubleRegister(instr->result()); 2444 XMMRegister result = ToDoubleRegister(instr->result());
2443 2445
2444 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2446 if (instr->hydrogen()->RequiresHoleCheck()) {
2445 sizeof(kHoleNanLower32); 2447 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2446 Operand hole_check_operand = BuildFastArrayOperand( 2448 sizeof(kHoleNanLower32);
2447 instr->elements(), instr->key(), 2449 Operand hole_check_operand = BuildFastArrayOperand(
2448 FAST_DOUBLE_ELEMENTS, 2450 instr->elements(), instr->key(),
2449 offset); 2451 FAST_DOUBLE_ELEMENTS,
2450 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); 2452 offset);
2451 DeoptimizeIf(equal, instr->environment()); 2453 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2454 DeoptimizeIf(equal, instr->environment());
2455 }
2452 2456
2453 Operand double_load_operand = BuildFastArrayOperand( 2457 Operand double_load_operand = BuildFastArrayOperand(
2454 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, 2458 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
2455 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 2459 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
2456 __ movdbl(result, double_load_operand); 2460 __ movdbl(result, double_load_operand);
2457 } 2461 }
2458 2462
2459 2463
2460 Operand LCodeGen::BuildFastArrayOperand( 2464 Operand LCodeGen::BuildFastArrayOperand(
2461 LOperand* elements_pointer, 2465 LOperand* elements_pointer,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2515 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2512 __ mov(result, operand); 2516 __ mov(result, operand);
2513 __ test(result, Operand(result)); 2517 __ test(result, Operand(result));
2514 // TODO(danno): we could be more clever here, perhaps having a special 2518 // TODO(danno): we could be more clever here, perhaps having a special
2515 // version of the stub that detects if the overflow case actually 2519 // version of the stub that detects if the overflow case actually
2516 // happens, and generate code that returns a double rather than int. 2520 // happens, and generate code that returns a double rather than int.
2517 DeoptimizeIf(negative, instr->environment()); 2521 DeoptimizeIf(negative, instr->environment());
2518 break; 2522 break;
2519 case EXTERNAL_FLOAT_ELEMENTS: 2523 case EXTERNAL_FLOAT_ELEMENTS:
2520 case EXTERNAL_DOUBLE_ELEMENTS: 2524 case EXTERNAL_DOUBLE_ELEMENTS:
2521 case FAST_SMI_ONLY_ELEMENTS: 2525 case FAST_SMI_ELEMENTS:
2522 case FAST_ELEMENTS: 2526 case FAST_ELEMENTS:
2523 case FAST_DOUBLE_ELEMENTS: 2527 case FAST_DOUBLE_ELEMENTS:
2528 case FAST_HOLEY_SMI_ELEMENTS:
2529 case FAST_HOLEY_ELEMENTS:
2530 case FAST_HOLEY_DOUBLE_ELEMENTS:
2524 case DICTIONARY_ELEMENTS: 2531 case DICTIONARY_ELEMENTS:
2525 case NON_STRICT_ARGUMENTS_ELEMENTS: 2532 case NON_STRICT_ARGUMENTS_ELEMENTS:
2526 UNREACHABLE(); 2533 UNREACHABLE();
2527 break; 2534 break;
2528 } 2535 }
2529 } 2536 }
2530 } 2537 }
2531 2538
2532 2539
2533 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2540 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
3424 case EXTERNAL_SHORT_ELEMENTS: 3431 case EXTERNAL_SHORT_ELEMENTS:
3425 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3432 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3426 __ mov_w(operand, value); 3433 __ mov_w(operand, value);
3427 break; 3434 break;
3428 case EXTERNAL_INT_ELEMENTS: 3435 case EXTERNAL_INT_ELEMENTS:
3429 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3436 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3430 __ mov(operand, value); 3437 __ mov(operand, value);
3431 break; 3438 break;
3432 case EXTERNAL_FLOAT_ELEMENTS: 3439 case EXTERNAL_FLOAT_ELEMENTS:
3433 case EXTERNAL_DOUBLE_ELEMENTS: 3440 case EXTERNAL_DOUBLE_ELEMENTS:
3434 case FAST_SMI_ONLY_ELEMENTS: 3441 case FAST_SMI_ELEMENTS:
3435 case FAST_ELEMENTS: 3442 case FAST_ELEMENTS:
3436 case FAST_DOUBLE_ELEMENTS: 3443 case FAST_DOUBLE_ELEMENTS:
3444 case FAST_HOLEY_SMI_ELEMENTS:
3445 case FAST_HOLEY_ELEMENTS:
3446 case FAST_HOLEY_DOUBLE_ELEMENTS:
3437 case DICTIONARY_ELEMENTS: 3447 case DICTIONARY_ELEMENTS:
3438 case NON_STRICT_ARGUMENTS_ELEMENTS: 3448 case NON_STRICT_ARGUMENTS_ELEMENTS:
3439 UNREACHABLE(); 3449 UNREACHABLE();
3440 break; 3450 break;
3441 } 3451 }
3442 } 3452 }
3443 } 3453 }
3444 3454
3445 3455
3446 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3456 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 3514 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
3505 __ movdbl(double_store_operand, value); 3515 __ movdbl(double_store_operand, value);
3506 } 3516 }
3507 3517
3508 3518
3509 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3519 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3510 ASSERT(ToRegister(instr->context()).is(esi)); 3520 ASSERT(ToRegister(instr->context()).is(esi));
3511 ASSERT(ToRegister(instr->object()).is(edx)); 3521 ASSERT(ToRegister(instr->object()).is(edx));
3512 ASSERT(ToRegister(instr->key()).is(ecx)); 3522 ASSERT(ToRegister(instr->key()).is(ecx));
3513 ASSERT(ToRegister(instr->value()).is(eax)); 3523 ASSERT(ToRegister(instr->value()).is(eax));
3514
3515 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3524 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3516 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3525 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3517 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3526 : isolate()->builtins()->KeyedStoreIC_Initialize();
3518 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3527 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3519 } 3528 }
3520 3529
3521 3530
3522 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 3531 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3523 Register object_reg = ToRegister(instr->object()); 3532 Register object_reg = ToRegister(instr->object());
3524 Register new_map_reg = ToRegister(instr->new_map_reg()); 3533 Register new_map_reg = ToRegister(instr->new_map_reg());
3525 3534
3526 Handle<Map> from_map = instr->original_map(); 3535 Handle<Map> from_map = instr->original_map();
3527 Handle<Map> to_map = instr->transitioned_map(); 3536 Handle<Map> to_map = instr->transitioned_map();
3528 ElementsKind from_kind = from_map->elements_kind(); 3537 ElementsKind from_kind = from_map->elements_kind();
3529 ElementsKind to_kind = to_map->elements_kind(); 3538 ElementsKind to_kind = to_map->elements_kind();
3530 3539
3531 Label not_applicable; 3540 Label not_applicable;
3532 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3541 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3533 __ j(not_equal, &not_applicable); 3542 __ j(not_equal, &not_applicable);
3534 __ mov(new_map_reg, to_map); 3543 __ mov(new_map_reg, to_map);
3535 if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { 3544 bool simple_map_change = (GetHoleyElementsKind(from_kind) == to_kind) ||
3545 (IsFastSmiElementsKind(from_kind) &&
3546 IsFastObjectElementsKind(to_kind));
3547 if (simple_map_change) {
3536 Register object_reg = ToRegister(instr->object()); 3548 Register object_reg = ToRegister(instr->object());
3537 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 3549 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
3538 // Write barrier. 3550 // Write barrier.
3539 ASSERT_NE(instr->temp_reg(), NULL); 3551 ASSERT_NE(instr->temp_reg(), NULL);
3540 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3552 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3541 ToRegister(instr->temp_reg()), kDontSaveFPRegs); 3553 ToRegister(instr->temp_reg()), kDontSaveFPRegs);
3542 } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && 3554 } else if (IsFastSmiElementsKind(from_kind) &&
3543 to_kind == FAST_DOUBLE_ELEMENTS) { 3555 IsFastDoubleElementsKind(to_kind)) {
3544 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3556 Register fixed_object_reg = ToRegister(instr->temp_reg());
3545 ASSERT(fixed_object_reg.is(edx)); 3557 ASSERT(fixed_object_reg.is(edx));
3546 ASSERT(new_map_reg.is(ebx)); 3558 ASSERT(new_map_reg.is(ebx));
3547 __ mov(fixed_object_reg, object_reg); 3559 __ mov(fixed_object_reg, object_reg);
3548 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3560 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3549 RelocInfo::CODE_TARGET, instr); 3561 RelocInfo::CODE_TARGET, instr);
3550 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 3562 } else if (IsFastDoubleElementsKind(from_kind) &&
3563 IsFastElementsKind(to_kind)) {
3551 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3564 Register fixed_object_reg = ToRegister(instr->temp_reg());
3552 ASSERT(fixed_object_reg.is(edx)); 3565 ASSERT(fixed_object_reg.is(edx));
3553 ASSERT(new_map_reg.is(ebx)); 3566 ASSERT(new_map_reg.is(ebx));
3554 __ mov(fixed_object_reg, object_reg); 3567 __ mov(fixed_object_reg, object_reg);
3555 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3568 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3556 RelocInfo::CODE_TARGET, instr); 3569 RelocInfo::CODE_TARGET, instr);
3557 } else { 3570 } else {
3558 UNREACHABLE(); 3571 UNREACHABLE();
3559 } 3572 }
3560 __ bind(&not_applicable); 3573 __ bind(&not_applicable);
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
4400 4413
4401 4414
4402 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4415 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4403 ASSERT(ToRegister(instr->context()).is(esi)); 4416 ASSERT(ToRegister(instr->context()).is(esi));
4404 Heap* heap = isolate()->heap(); 4417 Heap* heap = isolate()->heap();
4405 ElementsKind boilerplate_elements_kind = 4418 ElementsKind boilerplate_elements_kind =
4406 instr->hydrogen()->boilerplate_elements_kind(); 4419 instr->hydrogen()->boilerplate_elements_kind();
4407 4420
4408 // Deopt if the array literal boilerplate ElementsKind is of a type different 4421 // Deopt if the array literal boilerplate ElementsKind is of a type different
4409 // than the expected one. The check isn't necessary if the boilerplate has 4422 // than the expected one. The check isn't necessary if the boilerplate has
4410 // already been converted to FAST_ELEMENTS. 4423 // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4411 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4424 if (CanTransitionToMoreGeneralFastElementsKind(
4425 boilerplate_elements_kind, true)) {
4412 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object()); 4426 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object());
4413 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 4427 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
4414 // Load the map's "bit field 2". We only need the first byte, 4428 // Load the map's "bit field 2". We only need the first byte,
4415 // but the following masking takes care of that anyway. 4429 // but the following masking takes care of that anyway.
4416 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset)); 4430 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset));
4417 // Retrieve elements_kind from bit field 2. 4431 // Retrieve elements_kind from bit field 2.
4418 __ and_(ebx, Map::kElementsKindMask); 4432 __ and_(ebx, Map::kElementsKindMask);
4419 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift); 4433 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift);
4420 DeoptimizeIf(not_equal, instr->environment()); 4434 DeoptimizeIf(not_equal, instr->environment());
4421 } 4435 }
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
5025 FixedArray::kHeaderSize - kPointerSize)); 5039 FixedArray::kHeaderSize - kPointerSize));
5026 __ bind(&done); 5040 __ bind(&done);
5027 } 5041 }
5028 5042
5029 5043
5030 #undef __ 5044 #undef __
5031 5045
5032 } } // namespace v8::internal 5046 } } // namespace v8::internal
5033 5047
5034 #endif // V8_TARGET_ARCH_IA32 5048 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698