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

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

Issue 12221064: Implement many KeyedStoreStubs using Crankshaft (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 9 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2861 matching lines...) Expand 10 before | Expand all | Expand 10 after
2872 2872
2873 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( 2873 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
2874 Handle<Map> receiver_map) { 2874 Handle<Map> receiver_map) {
2875 // ----------- S t a t e ------------- 2875 // ----------- S t a t e -------------
2876 // -- eax : value 2876 // -- eax : value
2877 // -- ecx : key 2877 // -- ecx : key
2878 // -- edx : receiver 2878 // -- edx : receiver
2879 // -- esp[0] : return address 2879 // -- esp[0] : return address
2880 // ----------------------------------- 2880 // -----------------------------------
2881 ElementsKind elements_kind = receiver_map->elements_kind(); 2881 ElementsKind elements_kind = receiver_map->elements_kind();
2882 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 2882 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
2883 Handle<Code> stub = 2883 if ((receiver_map->has_fast_elements() ||
2884 KeyedStoreElementStub(is_jsarray, 2884 receiver_map->has_external_array_elements())) {
2885 elements_kind, 2885 Handle<Code> stub = KeyedStoreFastElementStub(
2886 store_mode_).GetCode(isolate()); 2886 is_js_array,
2887 2887 elements_kind,
2888 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); 2888 store_mode_).GetCode(isolate());
2889 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
2890 } else {
2891 Handle<Code> stub =
2892 KeyedStoreElementStub(is_js_array, elements_kind,
2893 store_mode_).GetCode(isolate());
2894 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
2895 }
2889 2896
2890 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2897 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2891 __ jmp(ic, RelocInfo::CODE_TARGET); 2898 __ jmp(ic, RelocInfo::CODE_TARGET);
2892 2899
2893 // Return the generated code. 2900 // Return the generated code.
2894 return GetCode(Code::NORMAL, factory()->empty_string()); 2901 return GetCode(Code::NORMAL, factory()->empty_string());
2895 } 2902 }
2896 2903
2897 2904
2898 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2905 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
3328 __ j(sign, fail); 3335 __ j(sign, fail);
3329 __ SmiTag(scratch); 3336 __ SmiTag(scratch);
3330 __ mov(key, scratch); 3337 __ mov(key, scratch);
3331 __ bind(&key_ok); 3338 __ bind(&key_ok);
3332 } else { 3339 } else {
3333 __ JumpIfNotSmi(key, fail); 3340 __ JumpIfNotSmi(key, fail);
3334 } 3341 }
3335 } 3342 }
3336 3343
3337 3344
3338 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
Jakob Kummerow 2013/03/11 16:36:07 Love this change! :-)
3339 MacroAssembler* masm,
3340 ElementsKind elements_kind) {
3341 // ----------- S t a t e -------------
3342 // -- eax : value
3343 // -- ecx : key
3344 // -- edx : receiver
3345 // -- esp[0] : return address
3346 // -----------------------------------
3347 Label miss_force_generic, slow, check_heap_number;
3348
3349 // This stub is meant to be tail-jumped to, the receiver must already
3350 // have been verified by the caller to not be a smi.
3351
3352 // Check that the key is a smi or a heap number convertible to a smi.
3353 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
3354
3355 // Check that the index is in range.
3356 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3357 __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset));
3358 // Unsigned comparison catches both negative and too-large values.
3359 __ j(above_equal, &slow);
3360
3361 // Handle both smis and HeapNumbers in the fast path. Go to the
3362 // runtime for all other kinds of values.
3363 // eax: value
3364 // edx: receiver
3365 // ecx: key
3366 // edi: elements array
3367 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
3368 __ JumpIfNotSmi(eax, &slow);
3369 } else {
3370 __ JumpIfNotSmi(eax, &check_heap_number);
3371 }
3372
3373 // smi case
3374 __ mov(ebx, eax); // Preserve the value in eax as the return value.
3375 __ SmiUntag(ebx);
3376 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3377 // edi: base pointer of external storage
3378 switch (elements_kind) {
3379 case EXTERNAL_PIXEL_ELEMENTS:
3380 __ ClampUint8(ebx);
3381 __ SmiUntag(ecx);
3382 __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
3383 break;
3384 case EXTERNAL_BYTE_ELEMENTS:
3385 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3386 __ SmiUntag(ecx);
3387 __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
3388 break;
3389 case EXTERNAL_SHORT_ELEMENTS:
3390 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3391 __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
3392 break;
3393 case EXTERNAL_INT_ELEMENTS:
3394 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3395 __ mov(Operand(edi, ecx, times_2, 0), ebx);
3396 break;
3397 case EXTERNAL_FLOAT_ELEMENTS:
3398 case EXTERNAL_DOUBLE_ELEMENTS:
3399 // Need to perform int-to-float conversion.
3400 __ push(ebx);
3401 __ fild_s(Operand(esp, 0));
3402 __ pop(ebx);
3403 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3404 __ fstp_s(Operand(edi, ecx, times_2, 0));
3405 } else { // elements_kind == EXTERNAL_DOUBLE_ELEMENTS.
3406 __ fstp_d(Operand(edi, ecx, times_4, 0));
3407 }
3408 break;
3409 default:
3410 UNREACHABLE();
3411 break;
3412 }
3413 __ ret(0); // Return the original value.
3414
3415 // TODO(danno): handle heap number -> pixel array conversion
3416 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
3417 __ bind(&check_heap_number);
3418 // eax: value
3419 // edx: receiver
3420 // ecx: key
3421 // edi: elements array
3422 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3423 Immediate(masm->isolate()->factory()->heap_number_map()));
3424 __ j(not_equal, &slow);
3425
3426 // The WebGL specification leaves the behavior of storing NaN and
3427 // +/-Infinity into integer arrays basically undefined. For more
3428 // reproducible behavior, convert these to zero.
3429 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3430 // edi: base pointer of external storage
3431 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3432 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3433 __ fstp_s(Operand(edi, ecx, times_2, 0));
3434 __ ret(0);
3435 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3436 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3437 __ fstp_d(Operand(edi, ecx, times_4, 0));
3438 __ ret(0);
3439 } else {
3440 // Perform float-to-int conversion with truncation (round-to-zero)
3441 // behavior.
3442
3443 // For the moment we make the slow call to the runtime on
3444 // processors that don't support SSE2. The code in IntegerConvert
3445 // (code-stubs-ia32.cc) is roughly what is needed here though the
3446 // conversion failure case does not need to be handled.
3447 if (CpuFeatures::IsSupported(SSE2)) {
3448 if ((elements_kind == EXTERNAL_INT_ELEMENTS ||
3449 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) &&
3450 CpuFeatures::IsSupported(SSE3)) {
3451 CpuFeatureScope scope(masm, SSE3);
3452 // fisttp stores values as signed integers. To represent the
3453 // entire range of int and unsigned int arrays, store as a
3454 // 64-bit int and discard the high 32 bits.
3455 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3456 __ sub(esp, Immediate(2 * kPointerSize));
3457 __ fisttp_d(Operand(esp, 0));
3458
3459 // If conversion failed (NaN, infinity, or a number outside
3460 // signed int64 range), the result is 0x8000000000000000, and
3461 // we must handle this case in the runtime.
3462 Label ok;
3463 __ cmp(Operand(esp, kPointerSize), Immediate(0x80000000u));
3464 __ j(not_equal, &ok);
3465 __ cmp(Operand(esp, 0), Immediate(0));
3466 __ j(not_equal, &ok);
3467 __ add(esp, Immediate(2 * kPointerSize)); // Restore the stack.
3468 __ jmp(&slow);
3469
3470 __ bind(&ok);
3471 __ pop(ebx);
3472 __ add(esp, Immediate(kPointerSize));
3473 __ mov(Operand(edi, ecx, times_2, 0), ebx);
3474 } else {
3475 ASSERT(CpuFeatures::IsSupported(SSE2));
3476 CpuFeatureScope scope(masm, SSE2);
3477 __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset));
3478 __ cmp(ebx, 0x80000000u);
3479 __ j(equal, &slow);
3480 // ebx: untagged integer value
3481 switch (elements_kind) {
3482 case EXTERNAL_PIXEL_ELEMENTS:
3483 __ ClampUint8(ebx);
3484 // Fall through.
3485 case EXTERNAL_BYTE_ELEMENTS:
3486 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3487 __ SmiUntag(ecx);
3488 __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
3489 break;
3490 case EXTERNAL_SHORT_ELEMENTS:
3491 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3492 __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
3493 break;
3494 case EXTERNAL_INT_ELEMENTS:
3495 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3496 __ mov(Operand(edi, ecx, times_2, 0), ebx);
3497 break;
3498 default:
3499 UNREACHABLE();
3500 break;
3501 }
3502 }
3503 __ ret(0); // Return original value.
3504 }
3505 }
3506 }
3507
3508 // Slow case: call runtime.
3509 __ bind(&slow);
3510 Counters* counters = masm->isolate()->counters();
3511 __ IncrementCounter(counters->keyed_store_external_array_slow(), 1);
3512
3513 // ----------- S t a t e -------------
3514 // -- eax : value
3515 // -- ecx : key
3516 // -- edx : receiver
3517 // -- esp[0] : return address
3518 // -----------------------------------
3519
3520 Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
3521 __ jmp(ic, RelocInfo::CODE_TARGET);
3522
3523 // ----------- S t a t e -------------
3524 // -- eax : value
3525 // -- ecx : key
3526 // -- edx : receiver
3527 // -- esp[0] : return address
3528 // -----------------------------------
3529
3530 __ bind(&miss_force_generic);
3531 Handle<Code> miss_ic =
3532 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3533 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3534 }
3535
3536
3537 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3345 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3538 MacroAssembler* masm, 3346 MacroAssembler* masm,
3539 bool is_js_array, 3347 bool is_js_array,
3540 ElementsKind elements_kind, 3348 ElementsKind elements_kind,
3541 KeyedAccessStoreMode store_mode) { 3349 KeyedAccessStoreMode store_mode) {
3542 // ----------- S t a t e ------------- 3350 // ----------- S t a t e -------------
3543 // -- eax : value 3351 // -- eax : value
3544 // -- ecx : key 3352 // -- ecx : key
3545 // -- edx : receiver 3353 // -- edx : receiver
3546 // -- esp[0] : return address 3354 // -- esp[0] : return address
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
3826 __ jmp(ic_slow, RelocInfo::CODE_TARGET); 3634 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3827 } 3635 }
3828 } 3636 }
3829 3637
3830 3638
3831 #undef __ 3639 #undef __
3832 3640
3833 } } // namespace v8::internal 3641 } } // namespace v8::internal
3834 3642
3835 #endif // V8_TARGET_ARCH_IA32 3643 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698