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

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

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 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
« no previous file with comments | « src/x64/simulator-x64.h ('k') | src/x64/virtual-frame-x64.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 2010 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
11 // with the distribution. 11 // with the distribution.
(...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 // Patch the receiver on the stack with the global proxy if 2053 // Patch the receiver on the stack with the global proxy if
2054 // necessary. 2054 // necessary.
2055 if (object->IsGlobalObject()) { 2055 if (object->IsGlobalObject()) {
2056 ASSERT(depth == kInvalidProtoDepth); 2056 ASSERT(depth == kInvalidProtoDepth);
2057 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2057 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2058 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2058 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
2059 } 2059 }
2060 break; 2060 break;
2061 2061
2062 case STRING_CHECK: 2062 case STRING_CHECK:
2063 if (!function->IsBuiltin()) { 2063 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2064 // Calling non-builtins with a value as receiver requires boxing. 2064 // Calling non-strict non-builtins with a value as the receiver
2065 // requires boxing.
2065 __ jmp(&miss); 2066 __ jmp(&miss);
2066 } else { 2067 } else {
2067 // Check that the object is a two-byte string or a symbol. 2068 // Check that the object is a two-byte string or a symbol.
2068 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); 2069 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
2069 __ j(above_equal, &miss); 2070 __ j(above_equal, &miss);
2070 // Check that the maps starting from the prototype haven't changed. 2071 // Check that the maps starting from the prototype haven't changed.
2071 GenerateDirectLoadGlobalFunctionPrototype( 2072 GenerateDirectLoadGlobalFunctionPrototype(
2072 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); 2073 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
2073 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 2074 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
2074 rbx, rdx, rdi, name, &miss); 2075 rbx, rdx, rdi, name, &miss);
2075 } 2076 }
2076 break; 2077 break;
2077 2078
2078 case NUMBER_CHECK: { 2079 case NUMBER_CHECK: {
2079 if (!function->IsBuiltin()) { 2080 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2080 // Calling non-builtins with a value as receiver requires boxing. 2081 // Calling non-strict non-builtins with a value as the receiver
2082 // requires boxing.
2081 __ jmp(&miss); 2083 __ jmp(&miss);
2082 } else { 2084 } else {
2083 Label fast; 2085 Label fast;
2084 // Check that the object is a smi or a heap number. 2086 // Check that the object is a smi or a heap number.
2085 __ JumpIfSmi(rdx, &fast); 2087 __ JumpIfSmi(rdx, &fast);
2086 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); 2088 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
2087 __ j(not_equal, &miss); 2089 __ j(not_equal, &miss);
2088 __ bind(&fast); 2090 __ bind(&fast);
2089 // Check that the maps starting from the prototype haven't changed. 2091 // Check that the maps starting from the prototype haven't changed.
2090 GenerateDirectLoadGlobalFunctionPrototype( 2092 GenerateDirectLoadGlobalFunctionPrototype(
2091 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); 2093 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
2092 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 2094 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
2093 rbx, rdx, rdi, name, &miss); 2095 rbx, rdx, rdi, name, &miss);
2094 } 2096 }
2095 break; 2097 break;
2096 } 2098 }
2097 2099
2098 case BOOLEAN_CHECK: { 2100 case BOOLEAN_CHECK: {
2099 if (!function->IsBuiltin()) { 2101 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2100 // Calling non-builtins with a value as receiver requires boxing. 2102 // Calling non-strict non-builtins with a value as the receiver
2103 // requires boxing.
2101 __ jmp(&miss); 2104 __ jmp(&miss);
2102 } else { 2105 } else {
2103 Label fast; 2106 Label fast;
2104 // Check that the object is a boolean. 2107 // Check that the object is a boolean.
2105 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); 2108 __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
2106 __ j(equal, &fast); 2109 __ j(equal, &fast);
2107 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); 2110 __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
2108 __ j(not_equal, &miss); 2111 __ j(not_equal, &miss);
2109 __ bind(&fast); 2112 __ bind(&fast);
2110 // Check that the maps starting from the prototype haven't changed. 2113 // Check that the maps starting from the prototype haven't changed.
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
2398 } 2401 }
2399 2402
2400 // Stub never generated for non-global objects that require access 2403 // Stub never generated for non-global objects that require access
2401 // checks. 2404 // checks.
2402 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); 2405 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
2403 2406
2404 __ pop(rbx); // remove the return address 2407 __ pop(rbx); // remove the return address
2405 __ push(rdx); // receiver 2408 __ push(rdx); // receiver
2406 __ push(rcx); // name 2409 __ push(rcx); // name
2407 __ push(rax); // value 2410 __ push(rax); // value
2411 __ Push(Smi::FromInt(strict_mode_));
2408 __ push(rbx); // restore return address 2412 __ push(rbx); // restore return address
2409 2413
2410 // Do tail-call to the runtime system. 2414 // Do tail-call to the runtime system.
2411 ExternalReference store_ic_property = 2415 ExternalReference store_ic_property =
2412 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); 2416 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
2413 __ TailCallExternalReference(store_ic_property, 3, 1); 2417 __ TailCallExternalReference(store_ic_property, 4, 1);
2414 2418
2415 // Handle store cache miss. 2419 // Handle store cache miss.
2416 __ bind(&miss); 2420 __ bind(&miss);
2417 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 2421 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
2418 __ Jump(ic, RelocInfo::CODE_TARGET); 2422 __ Jump(ic, RelocInfo::CODE_TARGET);
2419 2423
2420 // Return the generated code. 2424 // Return the generated code.
2421 return GetCode(INTERCEPTOR, name); 2425 return GetCode(INTERCEPTOR, name);
2422 } 2426 }
2423 2427
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2552 // Handle store cache miss. 2556 // Handle store cache miss.
2553 __ bind(&miss); 2557 __ bind(&miss);
2554 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); 2558 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
2555 __ jmp(ic, RelocInfo::CODE_TARGET); 2559 __ jmp(ic, RelocInfo::CODE_TARGET);
2556 2560
2557 // Return the generated code. 2561 // Return the generated code.
2558 return GetCode(NORMAL, NULL); 2562 return GetCode(NORMAL, NULL);
2559 } 2563 }
2560 2564
2561 2565
2562 MaybeObject* KeyedStoreStubCompiler::CompileStorePixelArray(
2563 JSObject* receiver) {
2564 // ----------- S t a t e -------------
2565 // -- rax : value
2566 // -- rcx : key
2567 // -- rdx : receiver
2568 // -- rsp[0] : return address
2569 // -----------------------------------
2570 Label miss;
2571
2572 // Check that the map matches.
2573 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, false);
2574
2575 // Do the load.
2576 GenerateFastPixelArrayStore(masm(),
2577 rdx,
2578 rcx,
2579 rax,
2580 rdi,
2581 rbx,
2582 true,
2583 false,
2584 &miss,
2585 &miss,
2586 NULL,
2587 &miss);
2588
2589 // Handle store cache miss.
2590 __ bind(&miss);
2591 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss));
2592 __ jmp(ic, RelocInfo::CODE_TARGET);
2593
2594 // Return the generated code.
2595 return GetCode(NORMAL, NULL);
2596 }
2597
2598
2599 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2566 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2600 JSObject* object, 2567 JSObject* object,
2601 JSObject* last) { 2568 JSObject* last) {
2602 // ----------- S t a t e ------------- 2569 // ----------- S t a t e -------------
2603 // -- rax : receiver 2570 // -- rax : receiver
2604 // -- rcx : name 2571 // -- rcx : name
2605 // -- rsp[0] : return address 2572 // -- rsp[0] : return address
2606 // ----------------------------------- 2573 // -----------------------------------
2607 Label miss; 2574 Label miss;
2608 2575
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
3028 __ ret(0); 2995 __ ret(0);
3029 2996
3030 __ bind(&miss); 2997 __ bind(&miss);
3031 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2998 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3032 2999
3033 // Return the generated code. 3000 // Return the generated code.
3034 return GetCode(NORMAL, NULL); 3001 return GetCode(NORMAL, NULL);
3035 } 3002 }
3036 3003
3037 3004
3038 MaybeObject* KeyedLoadStubCompiler::CompileLoadPixelArray(JSObject* receiver) {
3039 // ----------- S t a t e -------------
3040 // -- rax : key
3041 // -- rdx : receiver
3042 // -- esp[0] : return address
3043 // -----------------------------------
3044 Label miss;
3045
3046 // Check that the map matches.
3047 __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss, false);
3048
3049 GenerateFastPixelArrayLoad(masm(),
3050 rdx,
3051 rax,
3052 rbx,
3053 rcx,
3054 rax,
3055 &miss,
3056 &miss,
3057 &miss);
3058
3059 __ bind(&miss);
3060 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3061
3062 // Return the generated code.
3063 return GetCode(NORMAL, NULL);
3064 }
3065
3066
3067 // Specialized stub for constructing objects from functions which only have only 3005 // Specialized stub for constructing objects from functions which only have only
3068 // simple assignments of the form this.x = ...; in their body. 3006 // simple assignments of the form this.x = ...; in their body.
3069 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3007 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3070 // ----------- S t a t e ------------- 3008 // ----------- S t a t e -------------
3071 // -- rax : argc 3009 // -- rax : argc
3072 // -- rdi : constructor 3010 // -- rdi : constructor
3073 // -- rsp[0] : return address 3011 // -- rsp[0] : return address
3074 // -- rsp[4] : last argument 3012 // -- rsp[4] : last argument
3075 // ----------------------------------- 3013 // -----------------------------------
3076 Label generic_stub_call; 3014 Label generic_stub_call;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); 3127 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric);
3190 Handle<Code> generic_construct_stub(code); 3128 Handle<Code> generic_construct_stub(code);
3191 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 3129 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
3192 3130
3193 // Return the generated code. 3131 // Return the generated code.
3194 return GetCode(); 3132 return GetCode();
3195 } 3133 }
3196 3134
3197 3135
3198 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3136 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3199 ExternalArrayType array_type, Code::Flags flags) { 3137 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) {
3200 // ----------- S t a t e ------------- 3138 // ----------- S t a t e -------------
3201 // -- rax : key 3139 // -- rax : key
3202 // -- rdx : receiver 3140 // -- rdx : receiver
3203 // -- rsp[0] : return address 3141 // -- rsp[0] : return address
3204 // ----------------------------------- 3142 // -----------------------------------
3205 Label slow; 3143 Label slow;
3206 3144
3207 // Check that the object isn't a smi. 3145 // Check that the object isn't a smi.
3208 __ JumpIfSmi(rdx, &slow); 3146 __ JumpIfSmi(rdx, &slow);
3209 3147
3210 // Check that the key is a smi. 3148 // Check that the key is a smi.
3211 __ JumpIfNotSmi(rax, &slow); 3149 __ JumpIfNotSmi(rax, &slow);
3212 3150
3213 // Check that the object is a JS object. 3151 // Check that the map matches.
3214 __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); 3152 __ CheckMap(rdx, Handle<Map>(receiver->map()), &slow, false);
3215 __ j(not_equal, &slow);
3216 // Check that the receiver does not require access checks. We need
3217 // to check this explicitly since this generic stub does not perform
3218 // map checks. The map is already in rdx.
3219 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
3220 Immediate(1 << Map::kIsAccessCheckNeeded));
3221 __ j(not_zero, &slow);
3222
3223 // Check that the elements array is the appropriate type of
3224 // ExternalArray.
3225 // rax: index (as a smi)
3226 // rdx: JSObject
3227 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 3153 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
3228 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
3229 Heap::RootIndexForExternalArrayType(array_type));
3230 __ j(not_equal, &slow);
3231 3154
3232 // Check that the index is in range. 3155 // Check that the index is in range.
3233 __ SmiToInteger32(rcx, rax); 3156 __ SmiToInteger32(rcx, rax);
3234 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); 3157 __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset));
3235 // Unsigned comparison catches both negative and too-large values. 3158 // Unsigned comparison catches both negative and too-large values.
3236 __ j(above_equal, &slow); 3159 __ j(above_equal, &slow);
3237 3160
3238 // rax: index (as a smi) 3161 // rax: index (as a smi)
3239 // rdx: receiver (JSObject) 3162 // rdx: receiver (JSObject)
3240 // rcx: untagged index 3163 // rcx: untagged index
3241 // rbx: elements array 3164 // rbx: elements array
3242 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); 3165 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3243 // rbx: base pointer of external storage 3166 // rbx: base pointer of external storage
3244 switch (array_type) { 3167 switch (array_type) {
3245 case kExternalByteArray: 3168 case kExternalByteArray:
3246 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); 3169 __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0));
3247 break; 3170 break;
3171 case kExternalPixelArray:
3248 case kExternalUnsignedByteArray: 3172 case kExternalUnsignedByteArray:
3249 __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0)); 3173 __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0));
3250 break; 3174 break;
3251 case kExternalShortArray: 3175 case kExternalShortArray:
3252 __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0)); 3176 __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0));
3253 break; 3177 break;
3254 case kExternalUnsignedShortArray: 3178 case kExternalUnsignedShortArray:
3255 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); 3179 __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0));
3256 break; 3180 break;
3257 case kExternalIntArray: 3181 case kExternalIntArray:
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3330 3254
3331 // Perform tail call to the entry. 3255 // Perform tail call to the entry.
3332 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 3256 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
3333 3257
3334 // Return the generated code. 3258 // Return the generated code.
3335 return GetCode(flags); 3259 return GetCode(flags);
3336 } 3260 }
3337 3261
3338 3262
3339 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub( 3263 MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
3340 ExternalArrayType array_type, Code::Flags flags) { 3264 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags) {
3341 // ----------- S t a t e ------------- 3265 // ----------- S t a t e -------------
3342 // -- rax : value 3266 // -- rax : value
3343 // -- rcx : key 3267 // -- rcx : key
3344 // -- rdx : receiver 3268 // -- rdx : receiver
3345 // -- rsp[0] : return address 3269 // -- rsp[0] : return address
3346 // ----------------------------------- 3270 // -----------------------------------
3347 Label slow; 3271 Label slow;
3348 3272
3349 // Check that the object isn't a smi. 3273 // Check that the object isn't a smi.
3350 __ JumpIfSmi(rdx, &slow); 3274 __ JumpIfSmi(rdx, &slow);
3351 // Get the map from the receiver. 3275
3352 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 3276 // Check that the map matches.
3353 // Check that the receiver does not require access checks. We need 3277 __ CheckMap(rdx, Handle<Map>(receiver->map()), &slow, false);
3354 // to do this because this generic stub does not perform map checks. 3278 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
3355 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), 3279
3356 Immediate(1 << Map::kIsAccessCheckNeeded));
3357 __ j(not_zero, &slow);
3358 // Check that the key is a smi. 3280 // Check that the key is a smi.
3359 __ JumpIfNotSmi(rcx, &slow); 3281 __ JumpIfNotSmi(rcx, &slow);
3360 3282
3361 // Check that the object is a JS object.
3362 __ CmpInstanceType(rbx, JS_OBJECT_TYPE);
3363 __ j(not_equal, &slow);
3364
3365 // Check that the elements array is the appropriate type of
3366 // ExternalArray.
3367 // rax: value
3368 // rcx: key (a smi)
3369 // rdx: receiver (a JSObject)
3370 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
3371 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
3372 Heap::RootIndexForExternalArrayType(array_type));
3373 __ j(not_equal, &slow);
3374
3375 // Check that the index is in range. 3283 // Check that the index is in range.
3376 __ SmiToInteger32(rdi, rcx); // Untag the index. 3284 __ SmiToInteger32(rdi, rcx); // Untag the index.
3377 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset)); 3285 __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset));
3378 // Unsigned comparison catches both negative and too-large values. 3286 // Unsigned comparison catches both negative and too-large values.
3379 __ j(above_equal, &slow); 3287 __ j(above_equal, &slow);
3380 3288
3381 // Handle both smis and HeapNumbers in the fast path. Go to the 3289 // Handle both smis and HeapNumbers in the fast path. Go to the
3382 // runtime for all other kinds of values. 3290 // runtime for all other kinds of values.
3383 // rax: value 3291 // rax: value
3384 // rcx: key (a smi) 3292 // rcx: key (a smi)
3385 // rdx: receiver (a JSObject) 3293 // rdx: receiver (a JSObject)
3386 // rbx: elements array 3294 // rbx: elements array
3387 // rdi: untagged key 3295 // rdi: untagged key
3388 NearLabel check_heap_number; 3296 NearLabel check_heap_number;
3389 __ JumpIfNotSmi(rax, &check_heap_number); 3297 if (array_type == kExternalPixelArray) {
3298 // Float to pixel conversion is only implemented in the runtime for now.
3299 __ JumpIfNotSmi(rax, &slow);
3300 } else {
3301 __ JumpIfNotSmi(rax, &check_heap_number);
3302 }
3390 // No more branches to slow case on this path. Key and receiver not needed. 3303 // No more branches to slow case on this path. Key and receiver not needed.
3391 __ SmiToInteger32(rdx, rax); 3304 __ SmiToInteger32(rdx, rax);
3392 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); 3305 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3393 // rbx: base pointer of external storage 3306 // rbx: base pointer of external storage
3394 switch (array_type) { 3307 switch (array_type) {
3308 case kExternalPixelArray:
3309 { // Clamp the value to [0..255].
3310 NearLabel done;
3311 __ testl(rdx, Immediate(0xFFFFFF00));
3312 __ j(zero, &done);
3313 __ setcc(negative, rdx); // 1 if negative, 0 if positive.
3314 __ decb(rdx); // 0 if negative, 255 if positive.
3315 __ bind(&done);
3316 }
3317 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3318 break;
3395 case kExternalByteArray: 3319 case kExternalByteArray:
3396 case kExternalUnsignedByteArray: 3320 case kExternalUnsignedByteArray:
3397 __ movb(Operand(rbx, rdi, times_1, 0), rdx); 3321 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3398 break; 3322 break;
3399 case kExternalShortArray: 3323 case kExternalShortArray:
3400 case kExternalUnsignedShortArray: 3324 case kExternalUnsignedShortArray:
3401 __ movw(Operand(rbx, rdi, times_2, 0), rdx); 3325 __ movw(Operand(rbx, rdi, times_2, 0), rdx);
3402 break; 3326 break;
3403 case kExternalIntArray: 3327 case kExternalIntArray:
3404 case kExternalUnsignedIntArray: 3328 case kExternalUnsignedIntArray:
3405 __ movl(Operand(rbx, rdi, times_4, 0), rdx); 3329 __ movl(Operand(rbx, rdi, times_4, 0), rdx);
3406 break; 3330 break;
3407 case kExternalFloatArray: 3331 case kExternalFloatArray:
3408 // Need to perform int-to-float conversion. 3332 // Need to perform int-to-float conversion.
3409 __ cvtlsi2ss(xmm0, rdx); 3333 __ cvtlsi2ss(xmm0, rdx);
3410 __ movss(Operand(rbx, rdi, times_4, 0), xmm0); 3334 __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
3411 break; 3335 break;
3412 default: 3336 default:
3413 UNREACHABLE(); 3337 UNREACHABLE();
3414 break; 3338 break;
3415 } 3339 }
3416 __ ret(0); 3340 __ ret(0);
3417 3341
3418 __ bind(&check_heap_number); 3342 // TODO(danno): handle heap number -> pixel array conversion
3419 // rax: value 3343 if (array_type != kExternalPixelArray) {
3420 // rcx: key (a smi) 3344 __ bind(&check_heap_number);
3421 // rdx: receiver (a JSObject) 3345 // rax: value
3422 // rbx: elements array 3346 // rcx: key (a smi)
3423 // rdi: untagged key 3347 // rdx: receiver (a JSObject)
3424 __ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister); 3348 // rbx: elements array
3425 __ j(not_equal, &slow); 3349 // rdi: untagged key
3426 // No more branches to slow case on this path. 3350 __ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister);
3351 __ j(not_equal, &slow);
3352 // No more branches to slow case on this path.
3427 3353
3428 // The WebGL specification leaves the behavior of storing NaN and 3354 // The WebGL specification leaves the behavior of storing NaN and
3429 // +/-Infinity into integer arrays basically undefined. For more 3355 // +/-Infinity into integer arrays basically undefined. For more
3430 // reproducible behavior, convert these to zero. 3356 // reproducible behavior, convert these to zero.
3431 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); 3357 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
3432 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); 3358 __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
3433 // rdi: untagged index
3434 // rbx: base pointer of external storage
3435 // top of FPU stack: value
3436 if (array_type == kExternalFloatArray) {
3437 __ cvtsd2ss(xmm0, xmm0);
3438 __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
3439 __ ret(0);
3440 } else {
3441 // Perform float-to-int conversion with truncation (round-to-zero)
3442 // behavior.
3443
3444 // Convert to int32 and store the low byte/word.
3445 // If the value is NaN or +/-infinity, the result is 0x80000000,
3446 // which is automatically zero when taken mod 2^n, n < 32.
3447 // rdx: value (converted to an untagged integer)
3448 // rdi: untagged index 3359 // rdi: untagged index
3449 // rbx: base pointer of external storage 3360 // rbx: base pointer of external storage
3450 switch (array_type) { 3361 // top of FPU stack: value
3451 case kExternalByteArray: 3362 if (array_type == kExternalFloatArray) {
3452 case kExternalUnsignedByteArray: 3363 __ cvtsd2ss(xmm0, xmm0);
3453 __ cvttsd2si(rdx, xmm0); 3364 __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
3454 __ movb(Operand(rbx, rdi, times_1, 0), rdx); 3365 __ ret(0);
3455 break; 3366 } else {
3456 case kExternalShortArray: 3367 // Perform float-to-int conversion with truncation (round-to-zero)
3457 case kExternalUnsignedShortArray: 3368 // behavior.
3458 __ cvttsd2si(rdx, xmm0); 3369
3459 __ movw(Operand(rbx, rdi, times_2, 0), rdx); 3370 // Convert to int32 and store the low byte/word.
3460 break; 3371 // If the value is NaN or +/-infinity, the result is 0x80000000,
3461 case kExternalIntArray: 3372 // which is automatically zero when taken mod 2^n, n < 32.
3462 case kExternalUnsignedIntArray: { 3373 // rdx: value (converted to an untagged integer)
3463 // Convert to int64, so that NaN and infinities become 3374 // rdi: untagged index
3464 // 0x8000000000000000, which is zero mod 2^32. 3375 // rbx: base pointer of external storage
3465 __ cvttsd2siq(rdx, xmm0); 3376 switch (array_type) {
3466 __ movl(Operand(rbx, rdi, times_4, 0), rdx); 3377 case kExternalByteArray:
3467 break; 3378 case kExternalUnsignedByteArray:
3379 __ cvttsd2si(rdx, xmm0);
3380 __ movb(Operand(rbx, rdi, times_1, 0), rdx);
3381 break;
3382 case kExternalShortArray:
3383 case kExternalUnsignedShortArray:
3384 __ cvttsd2si(rdx, xmm0);
3385 __ movw(Operand(rbx, rdi, times_2, 0), rdx);
3386 break;
3387 case kExternalIntArray:
3388 case kExternalUnsignedIntArray: {
3389 // Convert to int64, so that NaN and infinities become
3390 // 0x8000000000000000, which is zero mod 2^32.
3391 __ cvttsd2siq(rdx, xmm0);
3392 __ movl(Operand(rbx, rdi, times_4, 0), rdx);
3393 break;
3394 }
3395 default:
3396 UNREACHABLE();
3397 break;
3468 } 3398 }
3469 default: 3399 __ ret(0);
3470 UNREACHABLE();
3471 break;
3472 } 3400 }
3473 __ ret(0);
3474 } 3401 }
3475 3402
3476 // Slow case: call runtime. 3403 // Slow case: call runtime.
3477 __ bind(&slow); 3404 __ bind(&slow);
3478 3405
3479 // ----------- S t a t e ------------- 3406 // ----------- S t a t e -------------
3480 // -- rax : value 3407 // -- rax : value
3481 // -- rcx : key 3408 // -- rcx : key
3482 // -- rdx : receiver 3409 // -- rdx : receiver
3483 // -- rsp[0] : return address 3410 // -- rsp[0] : return address
3484 // ----------------------------------- 3411 // -----------------------------------
3485 3412
3486 __ pop(rbx); 3413 __ pop(rbx);
3487 __ push(rdx); // receiver 3414 __ push(rdx); // receiver
3488 __ push(rcx); // key 3415 __ push(rcx); // key
3489 __ push(rax); // value 3416 __ push(rax); // value
3417 __ Push(Smi::FromInt(NONE)); // PropertyAttributes
3418 __ Push(Smi::FromInt(
3419 Code::ExtractExtraICStateFromFlags(flags) & kStrictMode));
3490 __ push(rbx); // return address 3420 __ push(rbx); // return address
3491 3421
3492 // Do tail-call to runtime routine. 3422 // Do tail-call to runtime routine.
3493 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 3423 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
3494 3424
3495 return GetCode(flags); 3425 return GetCode(flags);
3496 } 3426 }
3497 3427
3498 #undef __ 3428 #undef __
3499 3429
3500 } } // namespace v8::internal 3430 } } // namespace v8::internal
3501 3431
3502 #endif // V8_TARGET_ARCH_X64 3432 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/simulator-x64.h ('k') | src/x64/virtual-frame-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698