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