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

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: Review feedback 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/ic-ia32.cc ('k') | src/ia32/lithium-ia32.cc » ('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 2359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2370 __ j(equal, &done, Label::kNear); 2370 __ j(equal, &done, Label::kNear);
2371 __ cmp(FieldOperand(result, HeapObject::kMapOffset), 2371 __ cmp(FieldOperand(result, HeapObject::kMapOffset),
2372 Immediate(factory()->fixed_cow_array_map())); 2372 Immediate(factory()->fixed_cow_array_map()));
2373 __ j(equal, &done, Label::kNear); 2373 __ j(equal, &done, Label::kNear);
2374 Register temp((result.is(eax)) ? ebx : eax); 2374 Register temp((result.is(eax)) ? ebx : eax);
2375 __ push(temp); 2375 __ push(temp);
2376 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); 2376 __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
2377 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); 2377 __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset));
2378 __ and_(temp, Map::kElementsKindMask); 2378 __ and_(temp, Map::kElementsKindMask);
2379 __ shr(temp, Map::kElementsKindShift); 2379 __ shr(temp, Map::kElementsKindShift);
2380 __ cmp(temp, FAST_ELEMENTS); 2380 __ cmp(temp, GetInitialFastElementsKind());
2381 __ j(equal, &ok, Label::kNear); 2381 __ j(less, &fail, Label::kNear);
2382 __ cmp(temp, TERMINAL_FAST_ELEMENTS_KIND);
2383 __ j(less_equal, &ok, Label::kNear);
2382 __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 2384 __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
2383 __ j(less, &fail, Label::kNear); 2385 __ j(less, &fail, Label::kNear);
2384 __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); 2386 __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND);
2385 __ j(less_equal, &ok, Label::kNear); 2387 __ j(less_equal, &ok, Label::kNear);
2386 __ bind(&fail); 2388 __ bind(&fail);
2387 __ Abort("Check for fast or external elements failed."); 2389 __ Abort("Check for fast or external elements failed.");
2388 __ bind(&ok); 2390 __ bind(&ok);
2389 __ pop(temp); 2391 __ pop(temp);
2390 __ bind(&done); 2392 __ bind(&done);
2391 } 2393 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2432 __ cmp(result, factory()->the_hole_value()); 2434 __ cmp(result, factory()->the_hole_value());
2433 DeoptimizeIf(equal, instr->environment()); 2435 DeoptimizeIf(equal, instr->environment());
2434 } 2436 }
2435 } 2437 }
2436 2438
2437 2439
2438 void LCodeGen::DoLoadKeyedFastDoubleElement( 2440 void LCodeGen::DoLoadKeyedFastDoubleElement(
2439 LLoadKeyedFastDoubleElement* instr) { 2441 LLoadKeyedFastDoubleElement* instr) {
2440 XMMRegister result = ToDoubleRegister(instr->result()); 2442 XMMRegister result = ToDoubleRegister(instr->result());
2441 2443
2442 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2444 if (instr->hydrogen()->RequiresHoleCheck()) {
2443 sizeof(kHoleNanLower32); 2445 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2444 Operand hole_check_operand = BuildFastArrayOperand( 2446 sizeof(kHoleNanLower32);
2445 instr->elements(), instr->key(), 2447 Operand hole_check_operand = BuildFastArrayOperand(
2446 FAST_DOUBLE_ELEMENTS, 2448 instr->elements(), instr->key(),
2447 offset, 2449 FAST_DOUBLE_ELEMENTS,
2448 instr->additional_index()); 2450 offset,
2449 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); 2451 instr->additional_index());
2450 DeoptimizeIf(equal, instr->environment()); 2452 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2453 DeoptimizeIf(equal, instr->environment());
2454 }
2451 2455
2452 Operand double_load_operand = BuildFastArrayOperand( 2456 Operand double_load_operand = BuildFastArrayOperand(
2453 instr->elements(), 2457 instr->elements(),
2454 instr->key(), 2458 instr->key(),
2455 FAST_DOUBLE_ELEMENTS, 2459 FAST_DOUBLE_ELEMENTS,
2456 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 2460 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2457 instr->additional_index()); 2461 instr->additional_index());
2458 __ movdbl(result, double_load_operand); 2462 __ movdbl(result, double_load_operand);
2459 } 2463 }
2460 2464
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2521 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2525 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2522 __ mov(result, operand); 2526 __ mov(result, operand);
2523 __ test(result, Operand(result)); 2527 __ test(result, Operand(result));
2524 // TODO(danno): we could be more clever here, perhaps having a special 2528 // TODO(danno): we could be more clever here, perhaps having a special
2525 // version of the stub that detects if the overflow case actually 2529 // version of the stub that detects if the overflow case actually
2526 // happens, and generate code that returns a double rather than int. 2530 // happens, and generate code that returns a double rather than int.
2527 DeoptimizeIf(negative, instr->environment()); 2531 DeoptimizeIf(negative, instr->environment());
2528 break; 2532 break;
2529 case EXTERNAL_FLOAT_ELEMENTS: 2533 case EXTERNAL_FLOAT_ELEMENTS:
2530 case EXTERNAL_DOUBLE_ELEMENTS: 2534 case EXTERNAL_DOUBLE_ELEMENTS:
2531 case FAST_SMI_ONLY_ELEMENTS: 2535 case FAST_SMI_ELEMENTS:
2532 case FAST_ELEMENTS: 2536 case FAST_ELEMENTS:
2533 case FAST_DOUBLE_ELEMENTS: 2537 case FAST_DOUBLE_ELEMENTS:
2538 case FAST_HOLEY_SMI_ELEMENTS:
2539 case FAST_HOLEY_ELEMENTS:
2540 case FAST_HOLEY_DOUBLE_ELEMENTS:
2534 case DICTIONARY_ELEMENTS: 2541 case DICTIONARY_ELEMENTS:
2535 case NON_STRICT_ARGUMENTS_ELEMENTS: 2542 case NON_STRICT_ARGUMENTS_ELEMENTS:
2536 UNREACHABLE(); 2543 UNREACHABLE();
2537 break; 2544 break;
2538 } 2545 }
2539 } 2546 }
2540 } 2547 }
2541 2548
2542 2549
2543 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2550 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
3449 case EXTERNAL_SHORT_ELEMENTS: 3456 case EXTERNAL_SHORT_ELEMENTS:
3450 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3457 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3451 __ mov_w(operand, value); 3458 __ mov_w(operand, value);
3452 break; 3459 break;
3453 case EXTERNAL_INT_ELEMENTS: 3460 case EXTERNAL_INT_ELEMENTS:
3454 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3461 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3455 __ mov(operand, value); 3462 __ mov(operand, value);
3456 break; 3463 break;
3457 case EXTERNAL_FLOAT_ELEMENTS: 3464 case EXTERNAL_FLOAT_ELEMENTS:
3458 case EXTERNAL_DOUBLE_ELEMENTS: 3465 case EXTERNAL_DOUBLE_ELEMENTS:
3459 case FAST_SMI_ONLY_ELEMENTS: 3466 case FAST_SMI_ELEMENTS:
3460 case FAST_ELEMENTS: 3467 case FAST_ELEMENTS:
3461 case FAST_DOUBLE_ELEMENTS: 3468 case FAST_DOUBLE_ELEMENTS:
3469 case FAST_HOLEY_SMI_ELEMENTS:
3470 case FAST_HOLEY_ELEMENTS:
3471 case FAST_HOLEY_DOUBLE_ELEMENTS:
3462 case DICTIONARY_ELEMENTS: 3472 case DICTIONARY_ELEMENTS:
3463 case NON_STRICT_ARGUMENTS_ELEMENTS: 3473 case NON_STRICT_ARGUMENTS_ELEMENTS:
3464 UNREACHABLE(); 3474 UNREACHABLE();
3465 break; 3475 break;
3466 } 3476 }
3467 } 3477 }
3468 } 3478 }
3469 3479
3470 3480
3471 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3481 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3543 3553
3544 Handle<Map> from_map = instr->original_map(); 3554 Handle<Map> from_map = instr->original_map();
3545 Handle<Map> to_map = instr->transitioned_map(); 3555 Handle<Map> to_map = instr->transitioned_map();
3546 ElementsKind from_kind = from_map->elements_kind(); 3556 ElementsKind from_kind = from_map->elements_kind();
3547 ElementsKind to_kind = to_map->elements_kind(); 3557 ElementsKind to_kind = to_map->elements_kind();
3548 3558
3549 Label not_applicable; 3559 Label not_applicable;
3550 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3560 __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3551 __ j(not_equal, &not_applicable); 3561 __ j(not_equal, &not_applicable);
3552 __ mov(new_map_reg, to_map); 3562 __ mov(new_map_reg, to_map);
3553 if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { 3563 if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
3554 Register object_reg = ToRegister(instr->object()); 3564 Register object_reg = ToRegister(instr->object());
3555 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 3565 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
3556 // Write barrier. 3566 // Write barrier.
3557 ASSERT_NE(instr->temp_reg(), NULL); 3567 ASSERT_NE(instr->temp_reg(), NULL);
3558 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3568 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3559 ToRegister(instr->temp_reg()), kDontSaveFPRegs); 3569 ToRegister(instr->temp_reg()), kDontSaveFPRegs);
3560 } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && 3570 } else if (IsFastSmiElementsKind(from_kind) &&
3561 to_kind == FAST_DOUBLE_ELEMENTS) { 3571 IsFastDoubleElementsKind(to_kind)) {
3562 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3572 Register fixed_object_reg = ToRegister(instr->temp_reg());
3563 ASSERT(fixed_object_reg.is(edx)); 3573 ASSERT(fixed_object_reg.is(edx));
3564 ASSERT(new_map_reg.is(ebx)); 3574 ASSERT(new_map_reg.is(ebx));
3565 __ mov(fixed_object_reg, object_reg); 3575 __ mov(fixed_object_reg, object_reg);
3566 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3576 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3567 RelocInfo::CODE_TARGET, instr); 3577 RelocInfo::CODE_TARGET, instr);
3568 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 3578 } else if (IsFastDoubleElementsKind(from_kind) &&
3579 IsFastObjectElementsKind(to_kind)) {
3569 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3580 Register fixed_object_reg = ToRegister(instr->temp_reg());
3570 ASSERT(fixed_object_reg.is(edx)); 3581 ASSERT(fixed_object_reg.is(edx));
3571 ASSERT(new_map_reg.is(ebx)); 3582 ASSERT(new_map_reg.is(ebx));
3572 __ mov(fixed_object_reg, object_reg); 3583 __ mov(fixed_object_reg, object_reg);
3573 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3584 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3574 RelocInfo::CODE_TARGET, instr); 3585 RelocInfo::CODE_TARGET, instr);
3575 } else { 3586 } else {
3576 UNREACHABLE(); 3587 UNREACHABLE();
3577 } 3588 }
3578 __ bind(&not_applicable); 3589 __ bind(&not_applicable);
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
4418 4429
4419 4430
4420 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4431 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4421 ASSERT(ToRegister(instr->context()).is(esi)); 4432 ASSERT(ToRegister(instr->context()).is(esi));
4422 Heap* heap = isolate()->heap(); 4433 Heap* heap = isolate()->heap();
4423 ElementsKind boilerplate_elements_kind = 4434 ElementsKind boilerplate_elements_kind =
4424 instr->hydrogen()->boilerplate_elements_kind(); 4435 instr->hydrogen()->boilerplate_elements_kind();
4425 4436
4426 // Deopt if the array literal boilerplate ElementsKind is of a type different 4437 // Deopt if the array literal boilerplate ElementsKind is of a type different
4427 // than the expected one. The check isn't necessary if the boilerplate has 4438 // than the expected one. The check isn't necessary if the boilerplate has
4428 // already been converted to FAST_ELEMENTS. 4439 // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4429 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4440 if (CanTransitionToMoreGeneralFastElementsKind(
4441 boilerplate_elements_kind, true)) {
4430 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object()); 4442 __ LoadHeapObject(eax, instr->hydrogen()->boilerplate_object());
4431 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 4443 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
4432 // Load the map's "bit field 2". We only need the first byte, 4444 // Load the map's "bit field 2". We only need the first byte,
4433 // but the following masking takes care of that anyway. 4445 // but the following masking takes care of that anyway.
4434 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset)); 4446 __ mov(ebx, FieldOperand(ebx, Map::kBitField2Offset));
4435 // Retrieve elements_kind from bit field 2. 4447 // Retrieve elements_kind from bit field 2.
4436 __ and_(ebx, Map::kElementsKindMask); 4448 __ and_(ebx, Map::kElementsKindMask);
4437 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift); 4449 __ cmp(ebx, boilerplate_elements_kind << Map::kElementsKindShift);
4438 DeoptimizeIf(not_equal, instr->environment()); 4450 DeoptimizeIf(not_equal, instr->environment());
4439 } 4451 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
4581 4593
4582 4594
4583 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { 4595 void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
4584 ASSERT(ToRegister(instr->context()).is(esi)); 4596 ASSERT(ToRegister(instr->context()).is(esi));
4585 int size = instr->hydrogen()->total_size(); 4597 int size = instr->hydrogen()->total_size();
4586 ElementsKind boilerplate_elements_kind = 4598 ElementsKind boilerplate_elements_kind =
4587 instr->hydrogen()->boilerplate()->GetElementsKind(); 4599 instr->hydrogen()->boilerplate()->GetElementsKind();
4588 4600
4589 // Deopt if the literal boilerplate ElementsKind is of a type different than 4601 // Deopt if the literal boilerplate ElementsKind is of a type different than
4590 // the expected one. The check isn't necessary if the boilerplate has already 4602 // the expected one. The check isn't necessary if the boilerplate has already
4591 // been converted to FAST_ELEMENTS. 4603 // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4592 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4604 if (CanTransitionToMoreGeneralFastElementsKind(
4605 boilerplate_elements_kind, true)) {
4593 __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate()); 4606 __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate());
4594 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); 4607 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
4595 // Load the map's "bit field 2". We only need the first byte, 4608 // Load the map's "bit field 2". We only need the first byte,
4596 // but the following masking takes care of that anyway. 4609 // but the following masking takes care of that anyway.
4597 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); 4610 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
4598 // Retrieve elements_kind from bit field 2. 4611 // Retrieve elements_kind from bit field 2.
4599 __ and_(ecx, Map::kElementsKindMask); 4612 __ and_(ecx, Map::kElementsKindMask);
4600 __ cmp(ecx, boilerplate_elements_kind << Map::kElementsKindShift); 4613 __ cmp(ecx, boilerplate_elements_kind << Map::kElementsKindShift);
4601 DeoptimizeIf(not_equal, instr->environment()); 4614 DeoptimizeIf(not_equal, instr->environment());
4602 } 4615 }
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
5067 FixedArray::kHeaderSize - kPointerSize)); 5080 FixedArray::kHeaderSize - kPointerSize));
5068 __ bind(&done); 5081 __ bind(&done);
5069 } 5082 }
5070 5083
5071 5084
5072 #undef __ 5085 #undef __
5073 5086
5074 } } // namespace v8::internal 5087 } } // namespace v8::internal
5075 5088
5076 #endif // V8_TARGET_ARCH_IA32 5089 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698