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

Side by Side Diff: src/x64/ic-x64.cc

Issue 251041: Add pixel array handling in keyed IC's for x64 version. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 2 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/ic-ia32.cc ('k') | src/x64/macro-assembler-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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 } 250 }
251 #endif 251 #endif
252 252
253 253
254 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 254 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
255 // ----------- S t a t e ------------- 255 // ----------- S t a t e -------------
256 // -- rsp[0] : return address 256 // -- rsp[0] : return address
257 // -- rsp[8] : name 257 // -- rsp[8] : name
258 // -- rsp[16] : receiver 258 // -- rsp[16] : receiver
259 // ----------------------------------- 259 // -----------------------------------
260 Label slow, fast, check_string, index_int, index_string; 260 Label slow, check_string, index_int, index_string, check_pixel_array;
261 261
262 // Load name and receiver. 262 // Load name and receiver.
263 __ movq(rax, Operand(rsp, kPointerSize)); 263 __ movq(rax, Operand(rsp, kPointerSize));
264 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); 264 __ movq(rcx, Operand(rsp, 2 * kPointerSize));
265 265
266 // Check that the object isn't a smi. 266 // Check that the object isn't a smi.
267 __ JumpIfSmi(rcx, &slow); 267 __ JumpIfSmi(rcx, &slow);
268 268
269 // Check that the object is some kind of JS object EXCEPT JS Value type. 269 // Check that the object is some kind of JS object EXCEPT JS Value type.
270 // In the case that the object is a value-wrapper object, 270 // In the case that the object is a value-wrapper object,
271 // we enter the runtime system to make sure that indexing 271 // we enter the runtime system to make sure that indexing
272 // into string objects work as intended. 272 // into string objects work as intended.
273 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 273 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
274 __ CmpObjectType(rcx, JS_OBJECT_TYPE, rdx); 274 __ CmpObjectType(rcx, JS_OBJECT_TYPE, rdx);
275 __ j(below, &slow); 275 __ j(below, &slow);
276 // Check that the receiver does not require access checks. We need 276 // Check that the receiver does not require access checks. We need
277 // to check this explicitly since this generic stub does not perform 277 // to check this explicitly since this generic stub does not perform
278 // map checks. The map is already in rdx. 278 // map checks. The map is already in rdx.
279 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 279 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
280 Immediate(1 << Map::kIsAccessCheckNeeded)); 280 Immediate(1 << Map::kIsAccessCheckNeeded));
281 __ j(not_zero, &slow); 281 __ j(not_zero, &slow);
282 282
283 // Check that the key is a smi. 283 // Check that the key is a smi.
284 __ JumpIfNotSmi(rax, &check_string); 284 __ JumpIfNotSmi(rax, &check_string);
285 __ SmiToInteger32(rax, rax); 285 __ SmiToInteger32(rax, rax);
286 // Get the elements array of the object. 286 // Get the elements array of the object.
287 __ bind(&index_int); 287 __ bind(&index_int);
288 __ movq(rcx, FieldOperand(rcx, JSObject::kElementsOffset)); 288 __ movq(rcx, FieldOperand(rcx, JSObject::kElementsOffset));
289 // Check that the object is in fast mode (not dictionary). 289 // Check that the object is in fast mode (not dictionary).
290 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map()); 290 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
291 __ j(not_equal, &slow); 291 Heap::kFixedArrayMapRootIndex);
292 __ j(not_equal, &check_pixel_array);
292 // Check that the key (index) is within bounds. 293 // Check that the key (index) is within bounds.
293 __ cmpl(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); 294 __ cmpl(rax, FieldOperand(rcx, FixedArray::kLengthOffset));
294 __ j(below, &fast); // Unsigned comparison rejects negative indices. 295 __ j(above_equal, &slow); // Unsigned comparison rejects negative indices.
296 // Fast case: Do the load.
297 __ movq(rax, Operand(rcx, rax, times_pointer_size,
298 FixedArray::kHeaderSize - kHeapObjectTag));
299 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
300 // In case the loaded value is the_hole we have to consult GetProperty
301 // to ensure the prototype chain is searched.
302 __ j(equal, &slow);
303 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
304 __ ret(0);
305
306 // Check whether the elements is a pixel array.
307 // rax: untagged index
308 // rcx: elements array
309 __ bind(&check_pixel_array);
310 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
311 Heap::kPixelArrayMapRootIndex);
312 __ j(not_equal, &slow);
313 __ cmpl(rax, FieldOperand(rcx, PixelArray::kLengthOffset));
314 __ j(above_equal, &slow);
315 __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset));
316 __ movb(rax, Operand(rcx, rax, times_1, 0));
317 __ Integer32ToSmi(rax, rax);
318 __ ret(0);
319
295 // Slow case: Load name and receiver from stack and jump to runtime. 320 // Slow case: Load name and receiver from stack and jump to runtime.
296 __ bind(&slow); 321 __ bind(&slow);
297 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); 322 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
298 KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kKeyedGetProperty)); 323 KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kKeyedGetProperty));
299 __ bind(&check_string); 324 __ bind(&check_string);
300 // The key is not a smi. 325 // The key is not a smi.
301 // Is it a string? 326 // Is it a string?
302 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); 327 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx);
303 __ j(above_equal, &slow); 328 __ j(above_equal, &slow);
304 // Is the string an array index, with cached numeric value? 329 // Is the string an array index, with cached numeric value?
(...skipping 20 matching lines...) Expand all
325 (1 << (String::kShortLengthShift - String::kHashShift))); 350 (1 << (String::kShortLengthShift - String::kHashShift)));
326 __ bind(&index_string); 351 __ bind(&index_string);
327 const int kLengthFieldLimit = 352 const int kLengthFieldLimit =
328 (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift; 353 (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift;
329 __ cmpl(rbx, Immediate(kLengthFieldLimit)); 354 __ cmpl(rbx, Immediate(kLengthFieldLimit));
330 __ j(above_equal, &slow); 355 __ j(above_equal, &slow);
331 __ movl(rax, rbx); 356 __ movl(rax, rbx);
332 __ and_(rax, Immediate((1 << String::kShortLengthShift) - 1)); 357 __ and_(rax, Immediate((1 << String::kShortLengthShift) - 1));
333 __ shrl(rax, Immediate(String::kLongLengthShift)); 358 __ shrl(rax, Immediate(String::kLongLengthShift));
334 __ jmp(&index_int); 359 __ jmp(&index_int);
335 // Fast case: Do the load.
336 __ bind(&fast);
337 __ movq(rax, Operand(rcx, rax, times_pointer_size,
338 FixedArray::kHeaderSize - kHeapObjectTag));
339 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
340 // In case the loaded value is the_hole we have to consult GetProperty
341 // to ensure the prototype chain is searched.
342 __ j(equal, &slow);
343 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
344 __ ret(0);
345 } 360 }
346 361
347 362
348 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 363 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
349 // ----------- S t a t e ------------- 364 // ----------- S t a t e -------------
350 // -- rsp[0] : return address 365 // -- rsp[0] : return address
351 // -- rsp[8] : name 366 // -- rsp[8] : name
352 // -- rsp[16] : receiver 367 // -- rsp[16] : receiver
353 // ----------------------------------- 368 // -----------------------------------
354 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss))); 369 Generate(masm, ExternalReference(IC_Utility(kKeyedLoadIC_Miss)));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 } 410 }
396 411
397 412
398 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 413 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
399 // ----------- S t a t e ------------- 414 // ----------- S t a t e -------------
400 // -- rax : value 415 // -- rax : value
401 // -- rsp[0] : return address 416 // -- rsp[0] : return address
402 // -- rsp[8] : key 417 // -- rsp[8] : key
403 // -- rsp[16] : receiver 418 // -- rsp[16] : receiver
404 // ----------------------------------- 419 // -----------------------------------
405 Label slow, fast, array, extra; 420 Label slow, fast, array, extra, check_pixel_array;
406 421
407 // Get the receiver from the stack. 422 // Get the receiver from the stack.
408 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // 2 ~ return address, key 423 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // 2 ~ return address, key
409 // Check that the object isn't a smi. 424 // Check that the object isn't a smi.
410 __ JumpIfSmi(rdx, &slow); 425 __ JumpIfSmi(rdx, &slow);
411 // Get the map from the receiver. 426 // Get the map from the receiver.
412 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 427 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
413 // Check that the receiver does not require access checks. We need 428 // Check that the receiver does not require access checks. We need
414 // to do this because this generic stub does not perform map checks. 429 // to do this because this generic stub does not perform map checks.
415 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 430 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
(...skipping 12 matching lines...) Expand all
428 // Check that the object is some kind of JS object. 443 // Check that the object is some kind of JS object.
429 __ CmpInstanceType(rcx, FIRST_JS_OBJECT_TYPE); 444 __ CmpInstanceType(rcx, FIRST_JS_OBJECT_TYPE);
430 __ j(below, &slow); 445 __ j(below, &slow);
431 446
432 // Object case: Check key against length in the elements array. 447 // Object case: Check key against length in the elements array.
433 // rax: value 448 // rax: value
434 // rdx: JSObject 449 // rdx: JSObject
435 // rbx: index (as a smi), zero-extended. 450 // rbx: index (as a smi), zero-extended.
436 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 451 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
437 // Check that the object is in fast mode (not dictionary). 452 // Check that the object is in fast mode (not dictionary).
438 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map()); 453 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
439 __ j(not_equal, &slow); 454 Heap::kFixedArrayMapRootIndex);
455 __ j(not_equal, &check_pixel_array);
440 // Untag the key (for checking against untagged length in the fixed array). 456 // Untag the key (for checking against untagged length in the fixed array).
441 __ SmiToInteger32(rdx, rbx); 457 __ SmiToInteger32(rdx, rbx);
442 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset)); 458 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset));
443 // rax: value 459 // rax: value
444 // rcx: FixedArray 460 // rcx: FixedArray
445 // rbx: index (as a smi) 461 // rbx: index (as a smi)
446 __ j(below, &fast); 462 __ j(below, &fast);
447 463
448
449 // Slow case: Push extra copies of the arguments (3). 464 // Slow case: Push extra copies of the arguments (3).
450 __ bind(&slow); 465 __ bind(&slow);
451 __ pop(rcx); 466 __ pop(rcx);
452 __ push(Operand(rsp, 1 * kPointerSize)); 467 __ push(Operand(rsp, 1 * kPointerSize));
453 __ push(Operand(rsp, 1 * kPointerSize)); 468 __ push(Operand(rsp, 1 * kPointerSize));
454 __ push(rax); 469 __ push(rax);
455 __ push(rcx); 470 __ push(rcx);
456 // Do tail-call to runtime routine. 471 // Do tail-call to runtime routine.
457 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1); 472 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
458 473
474 // Check whether the elements is a pixel array.
475 // rax: value
476 // rcx: elements array
477 // rbx: index (as a smi), zero-extended.
478 __ bind(&check_pixel_array);
479 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
480 Heap::kPixelArrayMapRootIndex);
481 __ j(not_equal, &slow);
482 // Check that the value is a smi. If a conversion is needed call into the
483 // runtime to convert and clamp.
484 __ JumpIfNotSmi(rax, &slow);
485 __ SmiToInteger32(rbx, rbx);
486 __ cmpl(rbx, FieldOperand(rcx, PixelArray::kLengthOffset));
487 __ j(above_equal, &slow);
488 __ movq(rdx, rax); // Save the value.
489 __ SmiToInteger32(rax, rax);
490 { // Clamp the value to [0..255].
491 Label done, is_negative;
492 __ testl(rax, Immediate(0xFFFFFF00));
493 __ j(zero, &done);
494 __ j(negative, &is_negative);
Lasse Reichstein 2009/09/30 16:50:40 A thought: It might be faster to do the out-of-ran
Søren Thygesen Gjesse 2009/09/30 20:27:06 Nice jump-free clamping. I will try to see if it h
495 __ movl(rax, Immediate(255));
496 __ jmp(&done);
497 __ bind(&is_negative);
498 __ xorl(rax, rax); // Clear rax.
499 __ bind(&done);
500 }
501 __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset));
502 __ movb(Operand(rcx, rbx, times_1, 0), rax);
503 __ movq(rax, rdx); // Return the original value.
504 __ ret(0);
459 505
460 // Extra capacity case: Check if there is extra capacity to 506 // Extra capacity case: Check if there is extra capacity to
461 // perform the store and update the length. Used for adding one 507 // perform the store and update the length. Used for adding one
462 // element to the array by writing to array[array.length]. 508 // element to the array by writing to array[array.length].
463 __ bind(&extra); 509 __ bind(&extra);
464 // rax: value 510 // rax: value
465 // rdx: JSArray 511 // rdx: JSArray
466 // rcx: FixedArray 512 // rcx: FixedArray
467 // rbx: index (as a smi) 513 // rbx: index (as a smi)
468 // flags: compare (rbx, rdx.length()) 514 // flags: compare (rbx, rdx.length())
469 __ j(not_equal, &slow); // do not leave holes in the array 515 __ j(not_equal, &slow); // do not leave holes in the array
470 __ SmiToInteger64(rbx, rbx); 516 __ SmiToInteger64(rbx, rbx);
471 __ cmpl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); 517 __ cmpl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
472 __ j(above_equal, &slow); 518 __ j(above_equal, &slow);
473 // Increment and restore smi-tag. 519 // Increment and restore smi-tag.
474 __ Integer64AddToSmi(rbx, rbx, 1); 520 __ Integer64AddToSmi(rbx, rbx, 1);
475 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rbx); 521 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rbx);
476 __ SmiSubConstant(rbx, rbx, 1, NULL); 522 __ SmiSubConstant(rbx, rbx, 1, NULL);
477 __ jmp(&fast); 523 __ jmp(&fast);
478 524
479
480 // Array case: Get the length and the elements array from the JS 525 // Array case: Get the length and the elements array from the JS
481 // array. Check that the array is in fast mode; if it is the 526 // array. Check that the array is in fast mode; if it is the
482 // length is always a smi. 527 // length is always a smi.
483 __ bind(&array); 528 __ bind(&array);
484 // rax: value 529 // rax: value
485 // rdx: JSArray 530 // rdx: JSArray
486 // rbx: index (as a smi) 531 // rbx: index (as a smi)
487 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 532 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
488 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map()); 533 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map());
489 __ j(not_equal, &slow); 534 __ j(not_equal, &slow);
490 535
491 // Check the key against the length in the array, compute the 536 // Check the key against the length in the array, compute the
492 // address to store into and fall through to fast case. 537 // address to store into and fall through to fast case.
493 __ cmpl(rbx, FieldOperand(rdx, JSArray::kLengthOffset)); 538 __ cmpl(rbx, FieldOperand(rdx, JSArray::kLengthOffset));
494 __ j(above_equal, &extra); 539 __ j(above_equal, &extra);
495 540
496
497 // Fast case: Do the store. 541 // Fast case: Do the store.
498 __ bind(&fast); 542 __ bind(&fast);
499 // rax: value 543 // rax: value
500 // rcx: FixedArray 544 // rcx: FixedArray
501 // rbx: index (as a smi) 545 // rbx: index (as a smi)
502 __ movq(Operand(rcx, rbx, times_half_pointer_size, 546 __ movq(Operand(rcx, rbx, times_half_pointer_size,
503 FixedArray::kHeaderSize - kHeapObjectTag), 547 FixedArray::kHeaderSize - kHeapObjectTag),
504 rax); 548 rax);
505 // Update write barrier for the elements array address. 549 // Update write barrier for the elements array address.
506 __ movq(rdx, rax); 550 __ movq(rdx, rax);
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 1012
969 // Cache miss: Jump to runtime. 1013 // Cache miss: Jump to runtime.
970 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss))); 1014 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));
971 } 1015 }
972 1016
973 1017
974 #undef __ 1018 #undef __
975 1019
976 1020
977 } } // namespace v8::internal 1021 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698