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

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

Issue 12221064: Implement many KeyedStoreStubs using Crankshaft (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback 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 2684 matching lines...) Expand 10 before | Expand all | Expand 10 after
2695 Handle<Map> receiver_map) { 2695 Handle<Map> receiver_map) {
2696 // ----------- S t a t e ------------- 2696 // ----------- S t a t e -------------
2697 // -- rax : value 2697 // -- rax : value
2698 // -- rcx : key 2698 // -- rcx : key
2699 // -- rdx : receiver 2699 // -- rdx : receiver
2700 // -- rsp[0] : return address 2700 // -- rsp[0] : return address
2701 // ----------------------------------- 2701 // -----------------------------------
2702 2702
2703 ElementsKind elements_kind = receiver_map->elements_kind(); 2703 ElementsKind elements_kind = receiver_map->elements_kind();
2704 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 2704 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
2705 Handle<Code> stub = 2705 if (receiver_map->has_fast_elements() ||
2706 KeyedStoreElementStub(is_js_array, 2706 receiver_map->has_external_array_elements()) {
2707 elements_kind, 2707 Handle<Code> stub = KeyedStoreFastElementStub(
2708 store_mode_).GetCode(isolate()); 2708 is_js_array,
2709 2709 elements_kind,
2710 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); 2710 store_mode_).GetCode(isolate());
2711 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
2712 } else {
2713 Handle<Code> stub =
2714 KeyedStoreElementStub(is_js_array, elements_kind,
2715 store_mode_).GetCode(isolate());
2716 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
2717 }
2711 2718
2712 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2719 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2713 __ jmp(ic, RelocInfo::CODE_TARGET); 2720 __ jmp(ic, RelocInfo::CODE_TARGET);
2714 2721
2715 // Return the generated code. 2722 // Return the generated code.
2716 return GetCode(Code::NORMAL, factory()->empty_string()); 2723 return GetCode(Code::NORMAL, factory()->empty_string());
2717 } 2724 }
2718 2725
2719 2726
2720 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2727 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
3135 __ cvttsd2si(scratch, xmm_scratch0); 3142 __ cvttsd2si(scratch, xmm_scratch0);
3136 __ cvtlsi2sd(xmm_scratch1, scratch); 3143 __ cvtlsi2sd(xmm_scratch1, scratch);
3137 __ ucomisd(xmm_scratch1, xmm_scratch0); 3144 __ ucomisd(xmm_scratch1, xmm_scratch0);
3138 __ j(not_equal, fail); 3145 __ j(not_equal, fail);
3139 __ j(parity_even, fail); // NaN. 3146 __ j(parity_even, fail); // NaN.
3140 __ Integer32ToSmi(key, scratch); 3147 __ Integer32ToSmi(key, scratch);
3141 __ bind(&key_ok); 3148 __ bind(&key_ok);
3142 } 3149 }
3143 3150
3144 3151
3145 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3146 MacroAssembler* masm,
3147 ElementsKind elements_kind) {
3148 // ----------- S t a t e -------------
3149 // -- rax : value
3150 // -- rcx : key
3151 // -- rdx : receiver
3152 // -- rsp[0] : return address
3153 // -----------------------------------
3154 Label slow, miss_force_generic;
3155
3156 // This stub is meant to be tail-jumped to, the receiver must already
3157 // have been verified by the caller to not be a smi.
3158
3159 // Check that the key is a smi or a heap number convertible to a smi.
3160 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic);
3161
3162 // Check that the index is in range.
3163 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
3164 __ SmiToInteger32(rdi, rcx); // Untag the index.
3165 __ cmpq(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset));
3166 // Unsigned comparison catches both negative and too-large values.
3167 __ j(above_equal, &miss_force_generic);
3168
3169 // Handle both smis and HeapNumbers in the fast path. Go to the
3170 // runtime for all other kinds of values.
3171 // rax: value
3172 // rcx: key (a smi)
3173 // rdx: receiver (a JSObject)
3174 // rbx: elements array
3175 // rdi: untagged key
3176 Label check_heap_number;
3177 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
3178 // Float to pixel conversion is only implemented in the runtime for now.
3179 __ JumpIfNotSmi(rax, &slow);
3180 } else {
3181 __ JumpIfNotSmi(rax, &check_heap_number, Label::kNear);
3182 }
3183 // No more branches to slow case on this path. Key and receiver not needed.
3184 __ SmiToInteger32(rdx, rax);
3185 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3186 // rbx: base pointer of external storage
3187 switch (elements_kind) {
3188 case EXTERNAL_PIXEL_ELEMENTS:
3189 { // Clamp the value to [0..255].
3190 Label done;
3191 __ testl(rdx, Immediate(0xFFFFFF00));
3192 __ j(zero, &done, Label::kNear);
3193 __ setcc(negative, rdx); // 1 if negative, 0 if positive.
3194 __ decb(rdx); // 0 if negative, 255 if positive.
3195 __ bind(&done);
3196 }
3197 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3198 break;
3199 case EXTERNAL_BYTE_ELEMENTS:
3200 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3201 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3202 break;
3203 case EXTERNAL_SHORT_ELEMENTS:
3204 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3205 __ movw(Operand(rbx, rdi, times_2, 0), rdx);
3206 break;
3207 case EXTERNAL_INT_ELEMENTS:
3208 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3209 __ movl(Operand(rbx, rdi, times_4, 0), rdx);
3210 break;
3211 case EXTERNAL_FLOAT_ELEMENTS:
3212 // Need to perform int-to-float conversion.
3213 __ cvtlsi2ss(xmm0, rdx);
3214 __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
3215 break;
3216 case EXTERNAL_DOUBLE_ELEMENTS:
3217 // Need to perform int-to-float conversion.
3218 __ cvtlsi2sd(xmm0, rdx);
3219 __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
3220 break;
3221 case FAST_ELEMENTS:
3222 case FAST_SMI_ELEMENTS:
3223 case FAST_DOUBLE_ELEMENTS:
3224 case FAST_HOLEY_ELEMENTS:
3225 case FAST_HOLEY_SMI_ELEMENTS:
3226 case FAST_HOLEY_DOUBLE_ELEMENTS:
3227 case DICTIONARY_ELEMENTS:
3228 case NON_STRICT_ARGUMENTS_ELEMENTS:
3229 UNREACHABLE();
3230 break;
3231 }
3232 __ ret(0);
3233
3234 // TODO(danno): handle heap number -> pixel array conversion
3235 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
3236 __ bind(&check_heap_number);
3237 // rax: value
3238 // rcx: key (a smi)
3239 // rdx: receiver (a JSObject)
3240 // rbx: elements array
3241 // rdi: untagged key
3242 __ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister);
3243 __ j(not_equal, &slow);
3244 // No more branches to slow case on this path.
3245
3246 // The WebGL specification leaves the behavior of storing NaN and
3247 // +/-Infinity into integer arrays basically undefined. For more
3248 // reproducible behavior, convert these to zero.
3249 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
3250 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3251 // rdi: untagged index
3252 // rbx: base pointer of external storage
3253 // top of FPU stack: value
3254 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3255 __ cvtsd2ss(xmm0, xmm0);
3256 __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
3257 __ ret(0);
3258 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3259 __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
3260 __ ret(0);
3261 } else {
3262 // Perform float-to-int conversion with truncation (round-to-zero)
3263 // behavior.
3264 // Fast path: use machine instruction to convert to int64. If that
3265 // fails (out-of-range), go into the runtime.
3266 __ cvttsd2siq(r8, xmm0);
3267 __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
3268 __ cmpq(r8, kScratchRegister);
3269 __ j(equal, &slow);
3270
3271 // rdx: value (converted to an untagged integer)
3272 // rdi: untagged index
3273 // rbx: base pointer of external storage
3274 switch (elements_kind) {
3275 case EXTERNAL_BYTE_ELEMENTS:
3276 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3277 __ movb(Operand(rbx, rdi, times_1, 0), r8);
3278 break;
3279 case EXTERNAL_SHORT_ELEMENTS:
3280 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3281 __ movw(Operand(rbx, rdi, times_2, 0), r8);
3282 break;
3283 case EXTERNAL_INT_ELEMENTS:
3284 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3285 __ movl(Operand(rbx, rdi, times_4, 0), r8);
3286 break;
3287 case EXTERNAL_PIXEL_ELEMENTS:
3288 case EXTERNAL_FLOAT_ELEMENTS:
3289 case EXTERNAL_DOUBLE_ELEMENTS:
3290 case FAST_ELEMENTS:
3291 case FAST_SMI_ELEMENTS:
3292 case FAST_DOUBLE_ELEMENTS:
3293 case FAST_HOLEY_ELEMENTS:
3294 case FAST_HOLEY_SMI_ELEMENTS:
3295 case FAST_HOLEY_DOUBLE_ELEMENTS:
3296 case DICTIONARY_ELEMENTS:
3297 case NON_STRICT_ARGUMENTS_ELEMENTS:
3298 UNREACHABLE();
3299 break;
3300 }
3301 __ ret(0);
3302 }
3303 }
3304
3305 // Slow case: call runtime.
3306 __ bind(&slow);
3307
3308 // ----------- S t a t e -------------
3309 // -- rax : value
3310 // -- rcx : key
3311 // -- rdx : receiver
3312 // -- rsp[0] : return address
3313 // -----------------------------------
3314
3315 Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
3316 __ jmp(ic, RelocInfo::CODE_TARGET);
3317
3318 // Miss case: call runtime.
3319 __ bind(&miss_force_generic);
3320
3321 // ----------- S t a t e -------------
3322 // -- rax : value
3323 // -- rcx : key
3324 // -- rdx : receiver
3325 // -- rsp[0] : return address
3326 // -----------------------------------
3327
3328 Handle<Code> miss_ic =
3329 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3330 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3331 }
3332
3333
3334 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3152 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3335 MacroAssembler* masm, 3153 MacroAssembler* masm,
3336 bool is_js_array, 3154 bool is_js_array,
3337 ElementsKind elements_kind, 3155 ElementsKind elements_kind,
3338 KeyedAccessStoreMode store_mode) { 3156 KeyedAccessStoreMode store_mode) {
3339 // ----------- S t a t e ------------- 3157 // ----------- S t a t e -------------
3340 // -- rax : value 3158 // -- rax : value
3341 // -- rcx : key 3159 // -- rcx : key
3342 // -- rdx : receiver 3160 // -- rdx : receiver
3343 // -- rsp[0] : return address 3161 // -- rsp[0] : return address
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
3606 __ jmp(ic_slow, RelocInfo::CODE_TARGET); 3424 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3607 } 3425 }
3608 } 3426 }
3609 3427
3610 3428
3611 #undef __ 3429 #undef __
3612 3430
3613 } } // namespace v8::internal 3431 } } // namespace v8::internal
3614 3432
3615 #endif // V8_TARGET_ARCH_X64 3433 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/hydrogen.cc ('K') | « src/x64/code-stubs-x64.cc ('k') | test/mjsunit/elements-kind.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698