| 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 |