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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 7112010: Plumbing changes to merge various element kind implementaions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 years, 6 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/lithium-ia32.cc ('k') | src/ic.h » ('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 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 2681 matching lines...) Expand 10 before | Expand all | Expand 10 after
2692 __ bind(&miss); 2692 __ bind(&miss);
2693 __ DecrementCounter(counters->keyed_store_field(), 1); 2693 __ DecrementCounter(counters->keyed_store_field(), 1);
2694 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2694 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2695 __ jmp(ic, RelocInfo::CODE_TARGET); 2695 __ jmp(ic, RelocInfo::CODE_TARGET);
2696 2696
2697 // Return the generated code. 2697 // Return the generated code.
2698 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2698 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2699 } 2699 }
2700 2700
2701 2701
2702 MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( 2702 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(
2703 Map* receiver_map) { 2703 Map* receiver_map) {
2704 // ----------- S t a t e ------------- 2704 // ----------- S t a t e -------------
2705 // -- eax : value 2705 // -- eax : value
2706 // -- ecx : key 2706 // -- ecx : key
2707 // -- edx : receiver 2707 // -- edx : receiver
2708 // -- esp[0] : return address 2708 // -- esp[0] : return address
2709 // ----------------------------------- 2709 // -----------------------------------
2710 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 2710 MaybeObject* maybe_stub;
2711 MaybeObject* maybe_stub = 2711 if (receiver_map->has_fast_elements()) {
2712 KeyedStoreFastElementStub(is_js_array).TryGetCode(); 2712 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
2713 maybe_stub = KeyedStoreFastElementStub(is_js_array).TryGetCode();
2714 } else {
2715 ASSERT(receiver_map->has_external_array_elements());
2716 JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
2717 maybe_stub = KeyedStoreExternalArrayStub(elements_kind).TryGetCode();
2718 }
2713 Code* stub; 2719 Code* stub;
2714 if (!maybe_stub->To(&stub)) return maybe_stub; 2720 if (!maybe_stub->To(&stub)) return maybe_stub;
2715 __ DispatchMap(edx, 2721 __ DispatchMap(edx,
2716 Handle<Map>(receiver_map), 2722 Handle<Map>(receiver_map),
2717 Handle<Code>(stub), 2723 Handle<Code>(stub),
2718 DO_SMI_CHECK); 2724 DO_SMI_CHECK);
2719 2725
2720 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2726 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2721 __ jmp(ic, RelocInfo::CODE_TARGET); 2727 __ jmp(ic, RelocInfo::CODE_TARGET);
2722 2728
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
3156 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3162 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3157 __ bind(&miss); 3163 __ bind(&miss);
3158 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 3164 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
3159 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3165 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3160 3166
3161 // Return the generated code. 3167 // Return the generated code.
3162 return GetCode(CALLBACKS, name); 3168 return GetCode(CALLBACKS, name);
3163 } 3169 }
3164 3170
3165 3171
3166 MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { 3172 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
3167 // ----------- S t a t e ------------- 3173 // ----------- S t a t e -------------
3168 // -- eax : key 3174 // -- eax : key
3169 // -- edx : receiver 3175 // -- edx : receiver
3170 // -- esp[0] : return address 3176 // -- esp[0] : return address
3171 // ----------------------------------- 3177 // -----------------------------------
3172 MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode(); 3178 MaybeObject* maybe_stub;
3179 if (receiver_map->has_fast_elements()) {
3180 maybe_stub = KeyedLoadFastElementStub().TryGetCode();
3181 } else {
3182 ASSERT(receiver_map->has_external_array_elements());
3183 JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
3184 maybe_stub = KeyedLoadExternalArrayStub(elements_kind).TryGetCode();
3185 }
3173 Code* stub; 3186 Code* stub;
3174 if (!maybe_stub->To(&stub)) return maybe_stub; 3187 if (!maybe_stub->To(&stub)) return maybe_stub;
3175 __ DispatchMap(edx, 3188 __ DispatchMap(edx,
3176 Handle<Map>(receiver_map), 3189 Handle<Map>(receiver_map),
3177 Handle<Code>(stub), 3190 Handle<Code>(stub),
3178 DO_SMI_CHECK); 3191 DO_SMI_CHECK);
3179 3192
3180 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3193 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3181 3194
3182 // Return the generated code. 3195 // Return the generated code.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3344 __ bind(&generic_stub_call); 3357 __ bind(&generic_stub_call);
3345 Handle<Code> generic_construct_stub = 3358 Handle<Code> generic_construct_stub =
3346 isolate()->builtins()->JSConstructStubGeneric(); 3359 isolate()->builtins()->JSConstructStubGeneric();
3347 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3360 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3348 3361
3349 // Return the generated code. 3362 // Return the generated code.
3350 return GetCode(); 3363 return GetCode();
3351 } 3364 }
3352 3365
3353 3366
3354 MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
3355 JSObject*receiver, ExternalArrayType array_type) {
3356 // ----------- S t a t e -------------
3357 // -- eax : key
3358 // -- edx : receiver
3359 // -- esp[0] : return address
3360 // -----------------------------------
3361 MaybeObject* maybe_stub =
3362 KeyedLoadExternalArrayStub(array_type).TryGetCode();
3363 Code* stub;
3364 if (!maybe_stub->To(&stub)) return maybe_stub;
3365 __ DispatchMap(edx,
3366 Handle<Map>(receiver->map()),
3367 Handle<Code>(stub),
3368 DO_SMI_CHECK);
3369
3370 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3371 __ jmp(ic, RelocInfo::CODE_TARGET);
3372
3373 // Return the generated code.
3374 return GetCode();
3375 }
3376
3377
3378 MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
3379 JSObject* receiver, ExternalArrayType array_type) {
3380 // ----------- S t a t e -------------
3381 // -- eax : value
3382 // -- ecx : key
3383 // -- edx : receiver
3384 // -- esp[0] : return address
3385 // -----------------------------------
3386 MaybeObject* maybe_stub =
3387 KeyedStoreExternalArrayStub(array_type).TryGetCode();
3388 Code* stub;
3389 if (!maybe_stub->To(&stub)) return maybe_stub;
3390 __ DispatchMap(edx,
3391 Handle<Map>(receiver->map()),
3392 Handle<Code>(stub),
3393 DO_SMI_CHECK);
3394
3395 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
3396 __ jmp(ic, RelocInfo::CODE_TARGET);
3397
3398 return GetCode();
3399 }
3400
3401
3402 #undef __ 3367 #undef __
3403 #define __ ACCESS_MASM(masm) 3368 #define __ ACCESS_MASM(masm)
3404 3369
3405 3370
3406 void KeyedLoadStubCompiler::GenerateLoadExternalArray( 3371 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
3407 MacroAssembler* masm, 3372 MacroAssembler* masm,
3408 ExternalArrayType array_type) { 3373 JSObject::ElementsKind elements_kind) {
3409 // ----------- S t a t e ------------- 3374 // ----------- S t a t e -------------
3410 // -- eax : key 3375 // -- eax : key
3411 // -- edx : receiver 3376 // -- edx : receiver
3412 // -- esp[0] : return address 3377 // -- esp[0] : return address
3413 // ----------------------------------- 3378 // -----------------------------------
3414 Label miss_force_generic, failed_allocation, slow; 3379 Label miss_force_generic, failed_allocation, slow;
3415 3380
3416 // This stub is meant to be tail-jumped to, the receiver must already 3381 // This stub is meant to be tail-jumped to, the receiver must already
3417 // have been verified by the caller to not be a smi. 3382 // have been verified by the caller to not be a smi.
3418 3383
3419 // Check that the key is a smi. 3384 // Check that the key is a smi.
3420 __ test(eax, Immediate(kSmiTagMask)); 3385 __ test(eax, Immediate(kSmiTagMask));
3421 __ j(not_zero, &miss_force_generic); 3386 __ j(not_zero, &miss_force_generic);
3422 3387
3423 // Check that the index is in range. 3388 // Check that the index is in range.
3424 __ mov(ecx, eax); 3389 __ mov(ecx, eax);
3425 __ SmiUntag(ecx); // Untag the index. 3390 __ SmiUntag(ecx); // Untag the index.
3426 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 3391 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3427 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); 3392 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
3428 // Unsigned comparison catches both negative and too-large values. 3393 // Unsigned comparison catches both negative and too-large values.
3429 __ j(above_equal, &miss_force_generic); 3394 __ j(above_equal, &miss_force_generic);
3430 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); 3395 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
3431 // ebx: base pointer of external storage 3396 // ebx: base pointer of external storage
3432 switch (array_type) { 3397 switch (elements_kind) {
3433 case kExternalByteArray: 3398 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3434 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0)); 3399 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
3435 break; 3400 break;
3436 case kExternalUnsignedByteArray: 3401 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3437 case kExternalPixelArray: 3402 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3438 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0)); 3403 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
3439 break; 3404 break;
3440 case kExternalShortArray: 3405 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3441 __ movsx_w(eax, Operand(ebx, ecx, times_2, 0)); 3406 __ movsx_w(eax, Operand(ebx, ecx, times_2, 0));
3442 break; 3407 break;
3443 case kExternalUnsignedShortArray: 3408 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3444 __ movzx_w(eax, Operand(ebx, ecx, times_2, 0)); 3409 __ movzx_w(eax, Operand(ebx, ecx, times_2, 0));
3445 break; 3410 break;
3446 case kExternalIntArray: 3411 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3447 case kExternalUnsignedIntArray: 3412 case JSObject::EXTERNAL_INT_ELEMENTS:
3448 __ mov(ecx, Operand(ebx, ecx, times_4, 0)); 3413 __ mov(ecx, Operand(ebx, ecx, times_4, 0));
3449 break; 3414 break;
3450 case kExternalFloatArray: 3415 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3451 __ fld_s(Operand(ebx, ecx, times_4, 0)); 3416 __ fld_s(Operand(ebx, ecx, times_4, 0));
3452 break; 3417 break;
3453 case kExternalDoubleArray: 3418 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3454 __ fld_d(Operand(ebx, ecx, times_8, 0)); 3419 __ fld_d(Operand(ebx, ecx, times_8, 0));
3455 break; 3420 break;
3456 default: 3421 default:
3457 UNREACHABLE(); 3422 UNREACHABLE();
3458 break; 3423 break;
3459 } 3424 }
3460 3425
3461 // For integer array types: 3426 // For integer array types:
3462 // ecx: value 3427 // ecx: value
3463 // For floating-point array type: 3428 // For floating-point array type:
3464 // FP(0): value 3429 // FP(0): value
3465 3430
3466 if (array_type == kExternalIntArray || 3431 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS ||
3467 array_type == kExternalUnsignedIntArray) { 3432 elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
3468 // For the Int and UnsignedInt array types, we need to see whether 3433 // For the Int and UnsignedInt array types, we need to see whether
3469 // the value can be represented in a Smi. If not, we need to convert 3434 // the value can be represented in a Smi. If not, we need to convert
3470 // it to a HeapNumber. 3435 // it to a HeapNumber.
3471 Label box_int; 3436 Label box_int;
3472 if (array_type == kExternalIntArray) { 3437 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
3473 __ cmp(ecx, 0xC0000000); 3438 __ cmp(ecx, 0xC0000000);
3474 __ j(sign, &box_int); 3439 __ j(sign, &box_int);
3475 } else { 3440 } else {
3476 ASSERT_EQ(array_type, kExternalUnsignedIntArray); 3441 ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
3477 // The test is different for unsigned int values. Since we need 3442 // The test is different for unsigned int values. Since we need
3478 // the value to be in the range of a positive smi, we can't 3443 // the value to be in the range of a positive smi, we can't
3479 // handle either of the top two bits being set in the value. 3444 // handle either of the top two bits being set in the value.
3480 __ test(ecx, Immediate(0xC0000000)); 3445 __ test(ecx, Immediate(0xC0000000));
3481 __ j(not_zero, &box_int); 3446 __ j(not_zero, &box_int);
3482 } 3447 }
3483 3448
3484 __ mov(eax, ecx); 3449 __ mov(eax, ecx);
3485 __ SmiTag(eax); 3450 __ SmiTag(eax);
3486 __ ret(0); 3451 __ ret(0);
3487 3452
3488 __ bind(&box_int); 3453 __ bind(&box_int);
3489 3454
3490 // Allocate a HeapNumber for the int and perform int-to-double 3455 // Allocate a HeapNumber for the int and perform int-to-double
3491 // conversion. 3456 // conversion.
3492 if (array_type == kExternalIntArray) { 3457 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
3493 __ push(ecx); 3458 __ push(ecx);
3494 __ fild_s(Operand(esp, 0)); 3459 __ fild_s(Operand(esp, 0));
3495 __ pop(ecx); 3460 __ pop(ecx);
3496 } else { 3461 } else {
3497 ASSERT(array_type == kExternalUnsignedIntArray); 3462 ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
3498 // Need to zero-extend the value. 3463 // Need to zero-extend the value.
3499 // There's no fild variant for unsigned values, so zero-extend 3464 // There's no fild variant for unsigned values, so zero-extend
3500 // to a 64-bit int manually. 3465 // to a 64-bit int manually.
3501 __ push(Immediate(0)); 3466 __ push(Immediate(0));
3502 __ push(ecx); 3467 __ push(ecx);
3503 __ fild_d(Operand(esp, 0)); 3468 __ fild_d(Operand(esp, 0));
3504 __ pop(ecx); 3469 __ pop(ecx);
3505 __ pop(ecx); 3470 __ pop(ecx);
3506 } 3471 }
3507 // FP(0): value 3472 // FP(0): value
3508 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); 3473 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
3509 // Set the value. 3474 // Set the value.
3510 __ mov(eax, ecx); 3475 __ mov(eax, ecx);
3511 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3476 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
3512 __ ret(0); 3477 __ ret(0);
3513 } else if (array_type == kExternalFloatArray || 3478 } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
3514 array_type == kExternalDoubleArray) { 3479 elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
3515 // For the floating-point array type, we need to always allocate a 3480 // For the floating-point array type, we need to always allocate a
3516 // HeapNumber. 3481 // HeapNumber.
3517 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); 3482 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
3518 // Set the value. 3483 // Set the value.
3519 __ mov(eax, ecx); 3484 __ mov(eax, ecx);
3520 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3485 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
3521 __ ret(0); 3486 __ ret(0);
3522 } else { 3487 } else {
3523 __ SmiTag(eax); 3488 __ SmiTag(eax);
3524 __ ret(0); 3489 __ ret(0);
(...skipping 29 matching lines...) Expand all
3554 // Miss case: Jump to runtime. 3519 // Miss case: Jump to runtime.
3555 __ bind(&miss_force_generic); 3520 __ bind(&miss_force_generic);
3556 Handle<Code> miss_ic = 3521 Handle<Code> miss_ic =
3557 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); 3522 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3558 __ jmp(miss_ic, RelocInfo::CODE_TARGET); 3523 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3559 } 3524 }
3560 3525
3561 3526
3562 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3527 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3563 MacroAssembler* masm, 3528 MacroAssembler* masm,
3564 ExternalArrayType array_type) { 3529 JSObject::ElementsKind elements_kind) {
3565 // ----------- S t a t e ------------- 3530 // ----------- S t a t e -------------
3566 // -- eax : key 3531 // -- eax : key
3567 // -- edx : receiver 3532 // -- edx : receiver
3568 // -- esp[0] : return address 3533 // -- esp[0] : return address
3569 // ----------------------------------- 3534 // -----------------------------------
3570 Label miss_force_generic, slow, check_heap_number; 3535 Label miss_force_generic, slow, check_heap_number;
3571 3536
3572 // This stub is meant to be tail-jumped to, the receiver must already 3537 // This stub is meant to be tail-jumped to, the receiver must already
3573 // have been verified by the caller to not be a smi. 3538 // have been verified by the caller to not be a smi.
3574 3539
(...skipping 10 matching lines...) Expand all
3585 __ j(above_equal, &slow); 3550 __ j(above_equal, &slow);
3586 3551
3587 // Handle both smis and HeapNumbers in the fast path. Go to the 3552 // Handle both smis and HeapNumbers in the fast path. Go to the
3588 // runtime for all other kinds of values. 3553 // runtime for all other kinds of values.
3589 // eax: value 3554 // eax: value
3590 // edx: receiver 3555 // edx: receiver
3591 // ecx: key 3556 // ecx: key
3592 // edi: elements array 3557 // edi: elements array
3593 // ebx: untagged index 3558 // ebx: untagged index
3594 __ test(eax, Immediate(kSmiTagMask)); 3559 __ test(eax, Immediate(kSmiTagMask));
3595 if (array_type == kExternalPixelArray) 3560 if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS)
3596 __ j(not_equal, &slow); 3561 __ j(not_equal, &slow);
3597 else 3562 else
3598 __ j(not_equal, &check_heap_number); 3563 __ j(not_equal, &check_heap_number);
3599 3564
3600 // smi case 3565 // smi case
3601 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed. 3566 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed.
3602 __ SmiUntag(ecx); 3567 __ SmiUntag(ecx);
3603 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3568 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3604 // ecx: base pointer of external storage 3569 // ecx: base pointer of external storage
3605 switch (array_type) { 3570 switch (elements_kind) {
3606 case kExternalPixelArray: 3571 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3607 { // Clamp the value to [0..255]. 3572 { // Clamp the value to [0..255].
3608 Label done; 3573 Label done;
3609 __ test(ecx, Immediate(0xFFFFFF00)); 3574 __ test(ecx, Immediate(0xFFFFFF00));
3610 __ j(zero, &done, Label::kNear); 3575 __ j(zero, &done, Label::kNear);
3611 __ setcc(negative, ecx); // 1 if negative, 0 if positive. 3576 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3612 __ dec_b(ecx); // 0 if negative, 255 if positive. 3577 __ dec_b(ecx); // 0 if negative, 255 if positive.
3613 __ bind(&done); 3578 __ bind(&done);
3614 } 3579 }
3615 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3580 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3616 break; 3581 break;
3617 case kExternalByteArray: 3582 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3618 case kExternalUnsignedByteArray: 3583 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3619 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3584 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3620 break; 3585 break;
3621 case kExternalShortArray: 3586 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3622 case kExternalUnsignedShortArray: 3587 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3623 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3588 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3624 break; 3589 break;
3625 case kExternalIntArray: 3590 case JSObject::EXTERNAL_INT_ELEMENTS:
3626 case kExternalUnsignedIntArray: 3591 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3627 __ mov(Operand(edi, ebx, times_4, 0), ecx); 3592 __ mov(Operand(edi, ebx, times_4, 0), ecx);
3628 break; 3593 break;
3629 case kExternalFloatArray: 3594 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3630 case kExternalDoubleArray: 3595 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3631 // Need to perform int-to-float conversion. 3596 // Need to perform int-to-float conversion.
3632 __ push(ecx); 3597 __ push(ecx);
3633 __ fild_s(Operand(esp, 0)); 3598 __ fild_s(Operand(esp, 0));
3634 __ pop(ecx); 3599 __ pop(ecx);
3635 if (array_type == kExternalFloatArray) { 3600 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3636 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3601 __ fstp_s(Operand(edi, ebx, times_4, 0));
3637 } else { // array_type == kExternalDoubleArray. 3602 } else { // elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS.
3638 __ fstp_d(Operand(edi, ebx, times_8, 0)); 3603 __ fstp_d(Operand(edi, ebx, times_8, 0));
3639 } 3604 }
3640 break; 3605 break;
3641 default: 3606 default:
3642 UNREACHABLE(); 3607 UNREACHABLE();
3643 break; 3608 break;
3644 } 3609 }
3645 __ ret(0); // Return the original value. 3610 __ ret(0); // Return the original value.
3646 3611
3647 // TODO(danno): handle heap number -> pixel array conversion 3612 // TODO(danno): handle heap number -> pixel array conversion
3648 if (array_type != kExternalPixelArray) { 3613 if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
3649 __ bind(&check_heap_number); 3614 __ bind(&check_heap_number);
3650 // eax: value 3615 // eax: value
3651 // edx: receiver 3616 // edx: receiver
3652 // ecx: key 3617 // ecx: key
3653 // edi: elements array 3618 // edi: elements array
3654 // ebx: untagged index 3619 // ebx: untagged index
3655 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3620 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3656 Immediate(masm->isolate()->factory()->heap_number_map())); 3621 Immediate(masm->isolate()->factory()->heap_number_map()));
3657 __ j(not_equal, &slow); 3622 __ j(not_equal, &slow);
3658 3623
3659 // The WebGL specification leaves the behavior of storing NaN and 3624 // The WebGL specification leaves the behavior of storing NaN and
3660 // +/-Infinity into integer arrays basically undefined. For more 3625 // +/-Infinity into integer arrays basically undefined. For more
3661 // reproducible behavior, convert these to zero. 3626 // reproducible behavior, convert these to zero.
3662 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3627 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3663 // ebx: untagged index 3628 // ebx: untagged index
3664 // edi: base pointer of external storage 3629 // edi: base pointer of external storage
3665 if (array_type == kExternalFloatArray) { 3630 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3666 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3631 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3667 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3632 __ fstp_s(Operand(edi, ebx, times_4, 0));
3668 __ ret(0); 3633 __ ret(0);
3669 } else if (array_type == kExternalDoubleArray) { 3634 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
3670 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3635 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3671 __ fstp_d(Operand(edi, ebx, times_8, 0)); 3636 __ fstp_d(Operand(edi, ebx, times_8, 0));
3672 __ ret(0); 3637 __ ret(0);
3673 } else { 3638 } else {
3674 // Perform float-to-int conversion with truncation (round-to-zero) 3639 // Perform float-to-int conversion with truncation (round-to-zero)
3675 // behavior. 3640 // behavior.
3676 3641
3677 // For the moment we make the slow call to the runtime on 3642 // For the moment we make the slow call to the runtime on
3678 // processors that don't support SSE2. The code in IntegerConvert 3643 // processors that don't support SSE2. The code in IntegerConvert
3679 // (code-stubs-ia32.cc) is roughly what is needed here though the 3644 // (code-stubs-ia32.cc) is roughly what is needed here though the
3680 // conversion failure case does not need to be handled. 3645 // conversion failure case does not need to be handled.
3681 if (CpuFeatures::IsSupported(SSE2)) { 3646 if (CpuFeatures::IsSupported(SSE2)) {
3682 if (array_type != kExternalIntArray && 3647 if (elements_kind != JSObject::EXTERNAL_INT_ELEMENTS &&
3683 array_type != kExternalUnsignedIntArray) { 3648 elements_kind != JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
3684 ASSERT(CpuFeatures::IsSupported(SSE2)); 3649 ASSERT(CpuFeatures::IsSupported(SSE2));
3685 CpuFeatures::Scope scope(SSE2); 3650 CpuFeatures::Scope scope(SSE2);
3686 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); 3651 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3687 // ecx: untagged integer value 3652 // ecx: untagged integer value
3688 switch (array_type) { 3653 switch (elements_kind) {
3689 case kExternalPixelArray: 3654 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3690 { // Clamp the value to [0..255]. 3655 { // Clamp the value to [0..255].
3691 Label done; 3656 Label done;
3692 __ test(ecx, Immediate(0xFFFFFF00)); 3657 __ test(ecx, Immediate(0xFFFFFF00));
3693 __ j(zero, &done, Label::kNear); 3658 __ j(zero, &done, Label::kNear);
3694 __ setcc(negative, ecx); // 1 if negative, 0 if positive. 3659 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3695 __ dec_b(ecx); // 0 if negative, 255 if positive. 3660 __ dec_b(ecx); // 0 if negative, 255 if positive.
3696 __ bind(&done); 3661 __ bind(&done);
3697 } 3662 }
3698 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3663 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3699 break; 3664 break;
3700 case kExternalByteArray: 3665 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3701 case kExternalUnsignedByteArray: 3666 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3702 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3667 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3703 break; 3668 break;
3704 case kExternalShortArray: 3669 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3705 case kExternalUnsignedShortArray: 3670 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3706 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3671 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3707 break; 3672 break;
3708 default: 3673 default:
3709 UNREACHABLE(); 3674 UNREACHABLE();
3710 break; 3675 break;
3711 } 3676 }
3712 } else { 3677 } else {
3713 if (CpuFeatures::IsSupported(SSE3)) { 3678 if (CpuFeatures::IsSupported(SSE3)) {
3714 CpuFeatures::Scope scope(SSE3); 3679 CpuFeatures::Scope scope(SSE3);
3715 // fisttp stores values as signed integers. To represent the 3680 // fisttp stores values as signed integers. To represent the
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3768 // -- esp[0] : return address 3733 // -- esp[0] : return address
3769 // ----------------------------------- 3734 // -----------------------------------
3770 3735
3771 __ bind(&miss_force_generic); 3736 __ bind(&miss_force_generic);
3772 Handle<Code> miss_ic = 3737 Handle<Code> miss_ic =
3773 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3738 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3774 __ jmp(miss_ic, RelocInfo::CODE_TARGET); 3739 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3775 } 3740 }
3776 3741
3777 3742
3778
3779
3780 void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { 3743 void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
3781 // ----------- S t a t e ------------- 3744 // ----------- S t a t e -------------
3782 // -- eax : key 3745 // -- eax : key
3783 // -- edx : receiver 3746 // -- edx : receiver
3784 // -- esp[0] : return address 3747 // -- esp[0] : return address
3785 // ----------------------------------- 3748 // -----------------------------------
3786 Label miss_force_generic; 3749 Label miss_force_generic;
3787 3750
3788 // This stub is meant to be tail-jumped to, the receiver must already 3751 // This stub is meant to be tail-jumped to, the receiver must already
3789 // have been verified by the caller to not be a smi. 3752 // have been verified by the caller to not be a smi.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3862 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3825 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3863 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3826 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3864 } 3827 }
3865 3828
3866 3829
3867 #undef __ 3830 #undef __
3868 3831
3869 } } // namespace v8::internal 3832 } } // namespace v8::internal
3870 3833
3871 #endif // V8_TARGET_ARCH_IA32 3834 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698