OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2672 | 2672 |
2673 | 2673 |
2674 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { | 2674 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { |
2675 // ----------- S t a t e ------------- | 2675 // ----------- S t a t e ------------- |
2676 // -- eax : value | 2676 // -- eax : value |
2677 // -- ecx : key | 2677 // -- ecx : key |
2678 // -- edx : receiver | 2678 // -- edx : receiver |
2679 // -- esp[0] : return address | 2679 // -- esp[0] : return address |
2680 // ----------------------------------- | 2680 // ----------------------------------- |
2681 Code* stub; | 2681 Code* stub; |
2682 JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); | 2682 ElementsKind elements_kind = receiver_map->elements_kind(); |
2683 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 2683 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; |
2684 MaybeObject* maybe_stub = | 2684 MaybeObject* maybe_stub = |
2685 KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode(); | 2685 KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode(); |
2686 if (!maybe_stub->To(&stub)) return maybe_stub; | 2686 if (!maybe_stub->To(&stub)) return maybe_stub; |
2687 __ DispatchMap(edx, | 2687 __ DispatchMap(edx, |
2688 Handle<Map>(receiver_map), | 2688 Handle<Map>(receiver_map), |
2689 Handle<Code>(stub), | 2689 Handle<Code>(stub), |
2690 DO_SMI_CHECK); | 2690 DO_SMI_CHECK); |
2691 | 2691 |
2692 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2692 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 } | 3133 } |
3134 | 3134 |
3135 | 3135 |
3136 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { | 3136 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { |
3137 // ----------- S t a t e ------------- | 3137 // ----------- S t a t e ------------- |
3138 // -- eax : key | 3138 // -- eax : key |
3139 // -- edx : receiver | 3139 // -- edx : receiver |
3140 // -- esp[0] : return address | 3140 // -- esp[0] : return address |
3141 // ----------------------------------- | 3141 // ----------------------------------- |
3142 Code* stub; | 3142 Code* stub; |
3143 JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); | 3143 ElementsKind elements_kind = receiver_map->elements_kind(); |
3144 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); | 3144 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); |
3145 if (!maybe_stub->To(&stub)) return maybe_stub; | 3145 if (!maybe_stub->To(&stub)) return maybe_stub; |
3146 __ DispatchMap(edx, | 3146 __ DispatchMap(edx, |
3147 Handle<Map>(receiver_map), | 3147 Handle<Map>(receiver_map), |
3148 Handle<Code>(stub), | 3148 Handle<Code>(stub), |
3149 DO_SMI_CHECK); | 3149 DO_SMI_CHECK); |
3150 | 3150 |
3151 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3151 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3152 | 3152 |
3153 // Return the generated code. | 3153 // Return the generated code. |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3378 // ----------------------------------- | 3378 // ----------------------------------- |
3379 | 3379 |
3380 Handle<Code> miss_force_generic_ic = | 3380 Handle<Code> miss_force_generic_ic = |
3381 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3381 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
3382 __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET); | 3382 __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET); |
3383 } | 3383 } |
3384 | 3384 |
3385 | 3385 |
3386 void KeyedLoadStubCompiler::GenerateLoadExternalArray( | 3386 void KeyedLoadStubCompiler::GenerateLoadExternalArray( |
3387 MacroAssembler* masm, | 3387 MacroAssembler* masm, |
3388 JSObject::ElementsKind elements_kind) { | 3388 ElementsKind elements_kind) { |
3389 // ----------- S t a t e ------------- | 3389 // ----------- S t a t e ------------- |
3390 // -- eax : key | 3390 // -- eax : key |
3391 // -- edx : receiver | 3391 // -- edx : receiver |
3392 // -- esp[0] : return address | 3392 // -- esp[0] : return address |
3393 // ----------------------------------- | 3393 // ----------------------------------- |
3394 Label miss_force_generic, failed_allocation, slow; | 3394 Label miss_force_generic, failed_allocation, slow; |
3395 | 3395 |
3396 // This stub is meant to be tail-jumped to, the receiver must already | 3396 // This stub is meant to be tail-jumped to, the receiver must already |
3397 // have been verified by the caller to not be a smi. | 3397 // have been verified by the caller to not be a smi. |
3398 | 3398 |
3399 // Check that the key is a smi. | 3399 // Check that the key is a smi. |
3400 __ JumpIfNotSmi(eax, &miss_force_generic); | 3400 __ JumpIfNotSmi(eax, &miss_force_generic); |
3401 | 3401 |
3402 // Check that the index is in range. | 3402 // Check that the index is in range. |
3403 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | 3403 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
3404 __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset)); | 3404 __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset)); |
3405 // Unsigned comparison catches both negative and too-large values. | 3405 // Unsigned comparison catches both negative and too-large values. |
3406 __ j(above_equal, &miss_force_generic); | 3406 __ j(above_equal, &miss_force_generic); |
3407 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); | 3407 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); |
3408 // ebx: base pointer of external storage | 3408 // ebx: base pointer of external storage |
3409 switch (elements_kind) { | 3409 switch (elements_kind) { |
3410 case JSObject::EXTERNAL_BYTE_ELEMENTS: | 3410 case EXTERNAL_BYTE_ELEMENTS: |
3411 __ SmiUntag(eax); // Untag the index. | 3411 __ SmiUntag(eax); // Untag the index. |
3412 __ movsx_b(eax, Operand(ebx, eax, times_1, 0)); | 3412 __ movsx_b(eax, Operand(ebx, eax, times_1, 0)); |
3413 break; | 3413 break; |
3414 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3414 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3415 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | 3415 case EXTERNAL_PIXEL_ELEMENTS: |
3416 __ SmiUntag(eax); // Untag the index. | 3416 __ SmiUntag(eax); // Untag the index. |
3417 __ movzx_b(eax, Operand(ebx, eax, times_1, 0)); | 3417 __ movzx_b(eax, Operand(ebx, eax, times_1, 0)); |
3418 break; | 3418 break; |
3419 case JSObject::EXTERNAL_SHORT_ELEMENTS: | 3419 case EXTERNAL_SHORT_ELEMENTS: |
3420 __ movsx_w(eax, Operand(ebx, eax, times_1, 0)); | 3420 __ movsx_w(eax, Operand(ebx, eax, times_1, 0)); |
3421 break; | 3421 break; |
3422 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3422 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3423 __ movzx_w(eax, Operand(ebx, eax, times_1, 0)); | 3423 __ movzx_w(eax, Operand(ebx, eax, times_1, 0)); |
3424 break; | 3424 break; |
3425 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3425 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3426 case JSObject::EXTERNAL_INT_ELEMENTS: | 3426 case EXTERNAL_INT_ELEMENTS: |
3427 __ mov(ecx, Operand(ebx, eax, times_2, 0)); | 3427 __ mov(ecx, Operand(ebx, eax, times_2, 0)); |
3428 break; | 3428 break; |
3429 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | 3429 case EXTERNAL_FLOAT_ELEMENTS: |
3430 __ fld_s(Operand(ebx, eax, times_2, 0)); | 3430 __ fld_s(Operand(ebx, eax, times_2, 0)); |
3431 break; | 3431 break; |
3432 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: | 3432 case EXTERNAL_DOUBLE_ELEMENTS: |
3433 __ fld_d(Operand(ebx, eax, times_4, 0)); | 3433 __ fld_d(Operand(ebx, eax, times_4, 0)); |
3434 break; | 3434 break; |
3435 default: | 3435 default: |
3436 UNREACHABLE(); | 3436 UNREACHABLE(); |
3437 break; | 3437 break; |
3438 } | 3438 } |
3439 | 3439 |
3440 // For integer array types: | 3440 // For integer array types: |
3441 // ecx: value | 3441 // ecx: value |
3442 // For floating-point array type: | 3442 // For floating-point array type: |
3443 // FP(0): value | 3443 // FP(0): value |
3444 | 3444 |
3445 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS || | 3445 if (elements_kind == EXTERNAL_INT_ELEMENTS || |
3446 elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 3446 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
3447 // For the Int and UnsignedInt array types, we need to see whether | 3447 // For the Int and UnsignedInt array types, we need to see whether |
3448 // the value can be represented in a Smi. If not, we need to convert | 3448 // the value can be represented in a Smi. If not, we need to convert |
3449 // it to a HeapNumber. | 3449 // it to a HeapNumber. |
3450 Label box_int; | 3450 Label box_int; |
3451 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { | 3451 if (elements_kind == EXTERNAL_INT_ELEMENTS) { |
3452 __ cmp(ecx, 0xC0000000); | 3452 __ cmp(ecx, 0xC0000000); |
3453 __ j(sign, &box_int); | 3453 __ j(sign, &box_int); |
3454 } else { | 3454 } else { |
3455 ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); | 3455 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); |
3456 // The test is different for unsigned int values. Since we need | 3456 // The test is different for unsigned int values. Since we need |
3457 // the value to be in the range of a positive smi, we can't | 3457 // the value to be in the range of a positive smi, we can't |
3458 // handle either of the top two bits being set in the value. | 3458 // handle either of the top two bits being set in the value. |
3459 __ test(ecx, Immediate(0xC0000000)); | 3459 __ test(ecx, Immediate(0xC0000000)); |
3460 __ j(not_zero, &box_int); | 3460 __ j(not_zero, &box_int); |
3461 } | 3461 } |
3462 | 3462 |
3463 __ mov(eax, ecx); | 3463 __ mov(eax, ecx); |
3464 __ SmiTag(eax); | 3464 __ SmiTag(eax); |
3465 __ ret(0); | 3465 __ ret(0); |
3466 | 3466 |
3467 __ bind(&box_int); | 3467 __ bind(&box_int); |
3468 | 3468 |
3469 // Allocate a HeapNumber for the int and perform int-to-double | 3469 // Allocate a HeapNumber for the int and perform int-to-double |
3470 // conversion. | 3470 // conversion. |
3471 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { | 3471 if (elements_kind == EXTERNAL_INT_ELEMENTS) { |
3472 __ push(ecx); | 3472 __ push(ecx); |
3473 __ fild_s(Operand(esp, 0)); | 3473 __ fild_s(Operand(esp, 0)); |
3474 __ pop(ecx); | 3474 __ pop(ecx); |
3475 } else { | 3475 } else { |
3476 ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); | 3476 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); |
3477 // Need to zero-extend the value. | 3477 // Need to zero-extend the value. |
3478 // There's no fild variant for unsigned values, so zero-extend | 3478 // There's no fild variant for unsigned values, so zero-extend |
3479 // to a 64-bit int manually. | 3479 // to a 64-bit int manually. |
3480 __ push(Immediate(0)); | 3480 __ push(Immediate(0)); |
3481 __ push(ecx); | 3481 __ push(ecx); |
3482 __ fild_d(Operand(esp, 0)); | 3482 __ fild_d(Operand(esp, 0)); |
3483 __ pop(ecx); | 3483 __ pop(ecx); |
3484 __ pop(ecx); | 3484 __ pop(ecx); |
3485 } | 3485 } |
3486 // FP(0): value | 3486 // FP(0): value |
3487 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); | 3487 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); |
3488 // Set the value. | 3488 // Set the value. |
3489 __ mov(eax, ecx); | 3489 __ mov(eax, ecx); |
3490 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 3490 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3491 __ ret(0); | 3491 __ ret(0); |
3492 } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || | 3492 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
3493 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { | 3493 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3494 // For the floating-point array type, we need to always allocate a | 3494 // For the floating-point array type, we need to always allocate a |
3495 // HeapNumber. | 3495 // HeapNumber. |
3496 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); | 3496 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); |
3497 // Set the value. | 3497 // Set the value. |
3498 __ mov(eax, ecx); | 3498 __ mov(eax, ecx); |
3499 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 3499 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3500 __ ret(0); | 3500 __ ret(0); |
3501 } else { | 3501 } else { |
3502 __ SmiTag(eax); | 3502 __ SmiTag(eax); |
3503 __ ret(0); | 3503 __ ret(0); |
(...skipping 29 matching lines...) Expand all Loading... |
3533 // Miss case: Jump to runtime. | 3533 // Miss case: Jump to runtime. |
3534 __ bind(&miss_force_generic); | 3534 __ bind(&miss_force_generic); |
3535 Handle<Code> miss_ic = | 3535 Handle<Code> miss_ic = |
3536 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3536 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
3537 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3537 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3538 } | 3538 } |
3539 | 3539 |
3540 | 3540 |
3541 void KeyedStoreStubCompiler::GenerateStoreExternalArray( | 3541 void KeyedStoreStubCompiler::GenerateStoreExternalArray( |
3542 MacroAssembler* masm, | 3542 MacroAssembler* masm, |
3543 JSObject::ElementsKind elements_kind) { | 3543 ElementsKind elements_kind) { |
3544 // ----------- S t a t e ------------- | 3544 // ----------- S t a t e ------------- |
3545 // -- eax : key | 3545 // -- eax : key |
3546 // -- edx : receiver | 3546 // -- edx : receiver |
3547 // -- esp[0] : return address | 3547 // -- esp[0] : return address |
3548 // ----------------------------------- | 3548 // ----------------------------------- |
3549 Label miss_force_generic, slow, check_heap_number; | 3549 Label miss_force_generic, slow, check_heap_number; |
3550 | 3550 |
3551 // This stub is meant to be tail-jumped to, the receiver must already | 3551 // This stub is meant to be tail-jumped to, the receiver must already |
3552 // have been verified by the caller to not be a smi. | 3552 // have been verified by the caller to not be a smi. |
3553 | 3553 |
3554 // Check that the key is a smi. | 3554 // Check that the key is a smi. |
3555 __ JumpIfNotSmi(ecx, &miss_force_generic); | 3555 __ JumpIfNotSmi(ecx, &miss_force_generic); |
3556 | 3556 |
3557 // Check that the index is in range. | 3557 // Check that the index is in range. |
3558 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 3558 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
3559 __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset)); | 3559 __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset)); |
3560 // Unsigned comparison catches both negative and too-large values. | 3560 // Unsigned comparison catches both negative and too-large values. |
3561 __ j(above_equal, &slow); | 3561 __ j(above_equal, &slow); |
3562 | 3562 |
3563 // Handle both smis and HeapNumbers in the fast path. Go to the | 3563 // Handle both smis and HeapNumbers in the fast path. Go to the |
3564 // runtime for all other kinds of values. | 3564 // runtime for all other kinds of values. |
3565 // eax: value | 3565 // eax: value |
3566 // edx: receiver | 3566 // edx: receiver |
3567 // ecx: key | 3567 // ecx: key |
3568 // edi: elements array | 3568 // edi: elements array |
3569 if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { | 3569 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { |
3570 __ JumpIfNotSmi(eax, &slow); | 3570 __ JumpIfNotSmi(eax, &slow); |
3571 } else { | 3571 } else { |
3572 __ JumpIfNotSmi(eax, &check_heap_number); | 3572 __ JumpIfNotSmi(eax, &check_heap_number); |
3573 } | 3573 } |
3574 | 3574 |
3575 // smi case | 3575 // smi case |
3576 __ mov(ebx, eax); // Preserve the value in eax as the return value. | 3576 __ mov(ebx, eax); // Preserve the value in eax as the return value. |
3577 __ SmiUntag(ebx); | 3577 __ SmiUntag(ebx); |
3578 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); | 3578 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); |
3579 // edi: base pointer of external storage | 3579 // edi: base pointer of external storage |
3580 switch (elements_kind) { | 3580 switch (elements_kind) { |
3581 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | 3581 case EXTERNAL_PIXEL_ELEMENTS: |
3582 __ ClampUint8(ebx); | 3582 __ ClampUint8(ebx); |
3583 __ SmiUntag(ecx); | 3583 __ SmiUntag(ecx); |
3584 __ mov_b(Operand(edi, ecx, times_1, 0), ebx); | 3584 __ mov_b(Operand(edi, ecx, times_1, 0), ebx); |
3585 break; | 3585 break; |
3586 case JSObject::EXTERNAL_BYTE_ELEMENTS: | 3586 case EXTERNAL_BYTE_ELEMENTS: |
3587 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3587 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3588 __ SmiUntag(ecx); | 3588 __ SmiUntag(ecx); |
3589 __ mov_b(Operand(edi, ecx, times_1, 0), ebx); | 3589 __ mov_b(Operand(edi, ecx, times_1, 0), ebx); |
3590 break; | 3590 break; |
3591 case JSObject::EXTERNAL_SHORT_ELEMENTS: | 3591 case EXTERNAL_SHORT_ELEMENTS: |
3592 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3592 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3593 __ mov_w(Operand(edi, ecx, times_1, 0), ebx); | 3593 __ mov_w(Operand(edi, ecx, times_1, 0), ebx); |
3594 break; | 3594 break; |
3595 case JSObject::EXTERNAL_INT_ELEMENTS: | 3595 case EXTERNAL_INT_ELEMENTS: |
3596 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3596 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3597 __ mov(Operand(edi, ecx, times_2, 0), ebx); | 3597 __ mov(Operand(edi, ecx, times_2, 0), ebx); |
3598 break; | 3598 break; |
3599 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | 3599 case EXTERNAL_FLOAT_ELEMENTS: |
3600 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: | 3600 case EXTERNAL_DOUBLE_ELEMENTS: |
3601 // Need to perform int-to-float conversion. | 3601 // Need to perform int-to-float conversion. |
3602 __ push(ebx); | 3602 __ push(ebx); |
3603 __ fild_s(Operand(esp, 0)); | 3603 __ fild_s(Operand(esp, 0)); |
3604 __ pop(ebx); | 3604 __ pop(ebx); |
3605 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { | 3605 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3606 __ fstp_s(Operand(edi, ecx, times_2, 0)); | 3606 __ fstp_s(Operand(edi, ecx, times_2, 0)); |
3607 } else { // elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS. | 3607 } else { // elements_kind == EXTERNAL_DOUBLE_ELEMENTS. |
3608 __ fstp_d(Operand(edi, ecx, times_4, 0)); | 3608 __ fstp_d(Operand(edi, ecx, times_4, 0)); |
3609 } | 3609 } |
3610 break; | 3610 break; |
3611 default: | 3611 default: |
3612 UNREACHABLE(); | 3612 UNREACHABLE(); |
3613 break; | 3613 break; |
3614 } | 3614 } |
3615 __ ret(0); // Return the original value. | 3615 __ ret(0); // Return the original value. |
3616 | 3616 |
3617 // TODO(danno): handle heap number -> pixel array conversion | 3617 // TODO(danno): handle heap number -> pixel array conversion |
3618 if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { | 3618 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { |
3619 __ bind(&check_heap_number); | 3619 __ bind(&check_heap_number); |
3620 // eax: value | 3620 // eax: value |
3621 // edx: receiver | 3621 // edx: receiver |
3622 // ecx: key | 3622 // ecx: key |
3623 // edi: elements array | 3623 // edi: elements array |
3624 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), | 3624 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), |
3625 Immediate(masm->isolate()->factory()->heap_number_map())); | 3625 Immediate(masm->isolate()->factory()->heap_number_map())); |
3626 __ j(not_equal, &slow); | 3626 __ j(not_equal, &slow); |
3627 | 3627 |
3628 // The WebGL specification leaves the behavior of storing NaN and | 3628 // The WebGL specification leaves the behavior of storing NaN and |
3629 // +/-Infinity into integer arrays basically undefined. For more | 3629 // +/-Infinity into integer arrays basically undefined. For more |
3630 // reproducible behavior, convert these to zero. | 3630 // reproducible behavior, convert these to zero. |
3631 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); | 3631 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); |
3632 // edi: base pointer of external storage | 3632 // edi: base pointer of external storage |
3633 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { | 3633 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3634 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 3634 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3635 __ fstp_s(Operand(edi, ecx, times_2, 0)); | 3635 __ fstp_s(Operand(edi, ecx, times_2, 0)); |
3636 __ ret(0); | 3636 __ ret(0); |
3637 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { | 3637 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3638 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 3638 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3639 __ fstp_d(Operand(edi, ecx, times_4, 0)); | 3639 __ fstp_d(Operand(edi, ecx, times_4, 0)); |
3640 __ ret(0); | 3640 __ ret(0); |
3641 } else { | 3641 } else { |
3642 // Perform float-to-int conversion with truncation (round-to-zero) | 3642 // Perform float-to-int conversion with truncation (round-to-zero) |
3643 // behavior. | 3643 // behavior. |
3644 | 3644 |
3645 // For the moment we make the slow call to the runtime on | 3645 // For the moment we make the slow call to the runtime on |
3646 // processors that don't support SSE2. The code in IntegerConvert | 3646 // processors that don't support SSE2. The code in IntegerConvert |
3647 // (code-stubs-ia32.cc) is roughly what is needed here though the | 3647 // (code-stubs-ia32.cc) is roughly what is needed here though the |
3648 // conversion failure case does not need to be handled. | 3648 // conversion failure case does not need to be handled. |
3649 if (CpuFeatures::IsSupported(SSE2)) { | 3649 if (CpuFeatures::IsSupported(SSE2)) { |
3650 if (elements_kind != JSObject::EXTERNAL_INT_ELEMENTS && | 3650 if (elements_kind != EXTERNAL_INT_ELEMENTS && |
3651 elements_kind != JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 3651 elements_kind != EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
3652 ASSERT(CpuFeatures::IsSupported(SSE2)); | 3652 ASSERT(CpuFeatures::IsSupported(SSE2)); |
3653 CpuFeatures::Scope scope(SSE2); | 3653 CpuFeatures::Scope scope(SSE2); |
3654 __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset)); | 3654 __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset)); |
3655 // ecx: untagged integer value | 3655 // ecx: untagged integer value |
3656 switch (elements_kind) { | 3656 switch (elements_kind) { |
3657 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | 3657 case EXTERNAL_PIXEL_ELEMENTS: |
3658 __ ClampUint8(ebx); | 3658 __ ClampUint8(ebx); |
3659 // Fall through. | 3659 // Fall through. |
3660 case JSObject::EXTERNAL_BYTE_ELEMENTS: | 3660 case EXTERNAL_BYTE_ELEMENTS: |
3661 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3661 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3662 __ SmiUntag(ecx); | 3662 __ SmiUntag(ecx); |
3663 __ mov_b(Operand(edi, ecx, times_1, 0), ebx); | 3663 __ mov_b(Operand(edi, ecx, times_1, 0), ebx); |
3664 break; | 3664 break; |
3665 case JSObject::EXTERNAL_SHORT_ELEMENTS: | 3665 case EXTERNAL_SHORT_ELEMENTS: |
3666 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3666 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3667 __ mov_w(Operand(edi, ecx, times_1, 0), ebx); | 3667 __ mov_w(Operand(edi, ecx, times_1, 0), ebx); |
3668 break; | 3668 break; |
3669 default: | 3669 default: |
3670 UNREACHABLE(); | 3670 UNREACHABLE(); |
3671 break; | 3671 break; |
3672 } | 3672 } |
3673 } else { | 3673 } else { |
3674 if (CpuFeatures::IsSupported(SSE3)) { | 3674 if (CpuFeatures::IsSupported(SSE3)) { |
3675 CpuFeatures::Scope scope(SSE3); | 3675 CpuFeatures::Scope scope(SSE3); |
3676 // fisttp stores values as signed integers. To represent the | 3676 // fisttp stores values as signed integers. To represent the |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3979 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3979 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3980 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3980 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
3981 } | 3981 } |
3982 | 3982 |
3983 | 3983 |
3984 #undef __ | 3984 #undef __ |
3985 | 3985 |
3986 } } // namespace v8::internal | 3986 } } // namespace v8::internal |
3987 | 3987 |
3988 #endif // V8_TARGET_ARCH_IA32 | 3988 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |