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

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

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ia32 ready to go 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 2366 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 Immediate(factory()->fixed_cow_array_map())); 2377 Immediate(factory()->fixed_cow_array_map()));
2378 __ j(equal, &done, Label::kNear); 2378 __ j(equal, &done, Label::kNear);
2379 Register temp((result.is(eax)) ? ebx : eax); 2379 Register temp((result.is(eax)) ? ebx : eax);
2380 __ push(temp); 2380 __ push(temp);
2381 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); 2381 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
2382 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); 2382 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset));
2383 __ and_(temp, Map::kElementsKindMask); 2383 __ and_(temp, Map::kElementsKindMask);
2384 __ shr(temp, Map::kElementsKindShift); 2384 __ shr(temp, Map::kElementsKindShift);
2385 __ cmp(temp, FAST_ELEMENTS); 2385 __ cmp(temp, FAST_ELEMENTS);
2386 __ j(equal, &ok, Label::kNear); 2386 __ j(equal, &ok, Label::kNear);
2387 __ cmp(temp, FAST_HOLEY_ELEMENTS);
2388 __ j(equal, &ok, Label::kNear);
2387 __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 2389 __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
2388 __ j(less, &fail, Label::kNear); 2390 __ j(less, &fail, Label::kNear);
2389 __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); 2391 __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND);
2390 __ j(less_equal, &ok, Label::kNear); 2392 __ j(less_equal, &ok, Label::kNear);
2391 __ bind(&fail); 2393 __ bind(&fail);
2392 __ Abort("Check for fast or external elements failed."); 2394 __ Abort("Check for fast or external elements failed.");
2393 __ bind(&ok); 2395 __ bind(&ok);
2394 __ pop(temp); 2396 __ pop(temp);
2395 __ bind(&done); 2397 __ bind(&done);
2396 } 2398 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 if (instr->hydrogen()->RequiresHoleCheck()) {
2446 sizeof(kHoleNanLower32); 2448 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2447 Operand hole_check_operand = BuildFastArrayOperand( 2449 sizeof(kHoleNanLower32);
2448 instr->elements(), instr->key(), 2450 Operand hole_check_operand = BuildFastArrayOperand(
2449 FAST_DOUBLE_ELEMENTS, 2451 instr->elements(), instr->key(),
2450 offset); 2452 FAST_DOUBLE_ELEMENTS,
2451 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); 2453 offset);
2452 DeoptimizeIf(equal, instr->environment()); 2454 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2455 DeoptimizeIf(equal, instr->environment());
2456 }
2453 2457
2454 Operand double_load_operand = BuildFastArrayOperand( 2458 Operand double_load_operand = BuildFastArrayOperand(
2455 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, 2459 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
2456 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 2460 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
2457 __ movdbl(result, double_load_operand); 2461 __ movdbl(result, double_load_operand);
2458 } 2462 }
2459 2463
2460 2464
2461 Operand LCodeGen::BuildFastArrayOperand( 2465 Operand LCodeGen::BuildFastArrayOperand(
2462 LOperand* elements_pointer, 2466 LOperand* elements_pointer,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2512 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2516 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2513 __ mov(result, operand); 2517 __ mov(result, operand);
2514 __ test(result, Operand(result)); 2518 __ test(result, Operand(result));
2515 // TODO(danno): we could be more clever here, perhaps having a special 2519 // TODO(danno): we could be more clever here, perhaps having a special
2516 // version of the stub that detects if the overflow case actually 2520 // version of the stub that detects if the overflow case actually
2517 // happens, and generate code that returns a double rather than int. 2521 // happens, and generate code that returns a double rather than int.
2518 DeoptimizeIf(negative, instr->environment()); 2522 DeoptimizeIf(negative, instr->environment());
2519 break; 2523 break;
2520 case EXTERNAL_FLOAT_ELEMENTS: 2524 case EXTERNAL_FLOAT_ELEMENTS:
2521 case EXTERNAL_DOUBLE_ELEMENTS: 2525 case EXTERNAL_DOUBLE_ELEMENTS:
2522 case FAST_SMI_ONLY_ELEMENTS: 2526 case FAST_SMI_ELEMENTS:
2523 case FAST_ELEMENTS: 2527 case FAST_ELEMENTS:
2524 case FAST_DOUBLE_ELEMENTS: 2528 case FAST_DOUBLE_ELEMENTS:
2529 case FAST_HOLEY_SMI_ELEMENTS:
2530 case FAST_HOLEY_ELEMENTS:
2531 case FAST_HOLEY_DOUBLE_ELEMENTS:
2525 case DICTIONARY_ELEMENTS: 2532 case DICTIONARY_ELEMENTS:
2526 case NON_STRICT_ARGUMENTS_ELEMENTS: 2533 case NON_STRICT_ARGUMENTS_ELEMENTS:
2527 UNREACHABLE(); 2534 UNREACHABLE();
2528 break; 2535 break;
2529 } 2536 }
2530 } 2537 }
2531 } 2538 }
2532 2539
2533 2540
2534 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2541 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
3437 case EXTERNAL_SHORT_ELEMENTS: 3444 case EXTERNAL_SHORT_ELEMENTS:
3438 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3445 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3439 __ mov_w(operand, value); 3446 __ mov_w(operand, value);
3440 break; 3447 break;
3441 case EXTERNAL_INT_ELEMENTS: 3448 case EXTERNAL_INT_ELEMENTS:
3442 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3449 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3443 __ mov(operand, value); 3450 __ mov(operand, value);
3444 break; 3451 break;
3445 case EXTERNAL_FLOAT_ELEMENTS: 3452 case EXTERNAL_FLOAT_ELEMENTS:
3446 case EXTERNAL_DOUBLE_ELEMENTS: 3453 case EXTERNAL_DOUBLE_ELEMENTS:
3447 case FAST_SMI_ONLY_ELEMENTS: 3454 case FAST_SMI_ELEMENTS:
3448 case FAST_ELEMENTS: 3455 case FAST_ELEMENTS:
3449 case FAST_DOUBLE_ELEMENTS: 3456 case FAST_DOUBLE_ELEMENTS:
3457 case FAST_HOLEY_SMI_ELEMENTS:
3458 case FAST_HOLEY_ELEMENTS:
3459 case FAST_HOLEY_DOUBLE_ELEMENTS:
3450 case DICTIONARY_ELEMENTS: 3460 case DICTIONARY_ELEMENTS:
3451 case NON_STRICT_ARGUMENTS_ELEMENTS: 3461 case NON_STRICT_ARGUMENTS_ELEMENTS:
3452 UNREACHABLE(); 3462 UNREACHABLE();
3453 break; 3463 break;
3454 } 3464 }
3455 } 3465 }
3456 } 3466 }
3457 3467
3458 3468
3459 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3469 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3517 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 3527 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
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
3528 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3537 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3529 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3538 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3530 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3539 : isolate()->builtins()->KeyedStoreIC_Initialize();
3531 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3540 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3532 } 3541 }
3533 3542
3534 3543
3535 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 3544 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3536 Register object_reg = ToRegister(instr->object()); 3545 Register object_reg = ToRegister(instr->object());
3537 Register new_map_reg = ToRegister(instr->new_map_reg()); 3546 Register new_map_reg = ToRegister(instr->new_map_reg());
3538 3547
3539 Handle<Map> from_map = instr->original_map(); 3548 Handle<Map> from_map = instr->original_map();
3540 Handle<Map> to_map = instr->transitioned_map(); 3549 Handle<Map> to_map = instr->transitioned_map();
3541 ElementsKind from_kind = from_map->elements_kind(); 3550 ElementsKind from_kind = from_map->elements_kind();
3542 ElementsKind to_kind = to_map->elements_kind(); 3551 ElementsKind to_kind = to_map->elements_kind();
3543 3552
3544 Label not_applicable; 3553 Label not_applicable;
3545 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3554 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3546 __ j(not_equal, &not_applicable); 3555 __ j(not_equal, &not_applicable);
3547 __ mov(new_map_reg, to_map); 3556 __ mov(new_map_reg, to_map);
3548 if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { 3557 bool simple_map_change = (GetHoleyElementsKind(from_kind) == to_kind) ||
3558 (IsFastSmiElementsKind(from_kind) &&
3559 IsFastObjectElementsKind(to_kind));
3560 if (simple_map_change) {
3549 Register object_reg = ToRegister(instr->object()); 3561 Register object_reg = ToRegister(instr->object());
3550 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 3562 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
3551 // Write barrier. 3563 // Write barrier.
3552 ASSERT_NE(instr->temp_reg(), NULL); 3564 ASSERT_NE(instr->temp_reg(), NULL);
3553 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3565 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3554 ToRegister(instr->temp_reg()), kDontSaveFPRegs); 3566 ToRegister(instr->temp_reg()), kDontSaveFPRegs);
3555 } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && 3567 } else if (IsFastSmiElementsKind(from_kind) &&
3556 to_kind == FAST_DOUBLE_ELEMENTS) { 3568 IsFastDoubleElementsKind(to_kind)) {
3557 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3569 Register fixed_object_reg = ToRegister(instr->temp_reg());
3558 ASSERT(fixed_object_reg.is(edx)); 3570 ASSERT(fixed_object_reg.is(edx));
3559 ASSERT(new_map_reg.is(ebx)); 3571 ASSERT(new_map_reg.is(ebx));
3560 __ mov(fixed_object_reg, object_reg); 3572 __ mov(fixed_object_reg, object_reg);
3561 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3573 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3562 RelocInfo::CODE_TARGET, instr); 3574 RelocInfo::CODE_TARGET, instr);
3563 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 3575 } else if (IsFastDoubleElementsKind(from_kind) &&
3576 IsFastElementsKind(to_kind)) {
3564 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3577 Register fixed_object_reg = ToRegister(instr->temp_reg());
3565 ASSERT(fixed_object_reg.is(edx)); 3578 ASSERT(fixed_object_reg.is(edx));
3566 ASSERT(new_map_reg.is(ebx)); 3579 ASSERT(new_map_reg.is(ebx));
3567 __ mov(fixed_object_reg, object_reg); 3580 __ mov(fixed_object_reg, object_reg);
3568 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3581 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3569 RelocInfo::CODE_TARGET, instr); 3582 RelocInfo::CODE_TARGET, instr);
3570 } else { 3583 } else {
3571 UNREACHABLE(); 3584 UNREACHABLE();
3572 } 3585 }
3573 __ bind(&not_applicable); 3586 __ bind(&not_applicable);
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
4413 4426
4414 4427
4415 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4428 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4416 ASSERT(ToRegister(instr->context()).is(esi)); 4429 ASSERT(ToRegister(instr->context()).is(esi));
4417 Heap* heap = isolate()->heap(); 4430 Heap* heap = isolate()->heap();
4418 ElementsKind boilerplate_elements_kind = 4431 ElementsKind boilerplate_elements_kind =
4419 instr->hydrogen()->boilerplate_elements_kind(); 4432 instr->hydrogen()->boilerplate_elements_kind();
4420 4433
4421 // Deopt if the array literal boilerplate ElementsKind is of a type different 4434 // Deopt if the array literal boilerplate ElementsKind is of a type different
4422 // than the expected one. The check isn't necessary if the boilerplate has 4435 // than the expected one. The check isn't necessary if the boilerplate has
4423 // already been converted to FAST_ELEMENTS. 4436 // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4424 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4437 if (CanTransitionToMoreGeneralFastElementsKind(
4438 boilerplate_elements_kind, true)) {
4425 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object()); 4439 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object());
4426 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 4440 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
4427 // Load the map's "bit field 2". We only need the first byte, 4441 // Load the map's "bit field 2". We only need the first byte,
4428 // but the following masking takes care of that anyway. 4442 // but the following masking takes care of that anyway.
4429 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset)); 4443 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset));
4430 // Retrieve elements_kind from bit field 2. 4444 // Retrieve elements_kind from bit field 2.
4431 __ and_(ebx, Map::kElementsKindMask); 4445 __ and_(ebx, Map::kElementsKindMask);
4432 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift); 4446 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift);
4433 DeoptimizeIf(not_equal, instr->environment()); 4447 DeoptimizeIf(not_equal, instr->environment());
4434 } 4448 }
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
5062 FixedArray::kHeaderSize - kPointerSize)); 5076 FixedArray::kHeaderSize - kPointerSize));
5063 __ bind(&done); 5077 __ bind(&done);
5064 } 5078 }
5065 5079
5066 5080
5067 #undef __ 5081 #undef __
5068 5082
5069 } } // namespace v8::internal 5083 } } // namespace v8::internal
5070 5084
5071 #endif // V8_TARGET_ARCH_IA32 5085 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698