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

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

Issue 3144002: Copy-on-write arrays. (Closed)
Patch Set: Review fixes. Created 10 years, 4 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
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.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 2010 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 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 // we enter the runtime system to make sure that indexing 445 // we enter the runtime system to make sure that indexing
446 // into string objects works as intended. 446 // into string objects works as intended.
447 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 447 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
448 448
449 __ CmpInstanceType(map, JS_OBJECT_TYPE); 449 __ CmpInstanceType(map, JS_OBJECT_TYPE);
450 __ j(below, slow, not_taken); 450 __ j(below, slow, not_taken);
451 } 451 }
452 452
453 453
454 // Loads an indexed element from a fast case array. 454 // Loads an indexed element from a fast case array.
455 // If not_fast_array is NULL, doesn't perform the elements map check.
455 static void GenerateFastArrayLoad(MacroAssembler* masm, 456 static void GenerateFastArrayLoad(MacroAssembler* masm,
456 Register receiver, 457 Register receiver,
457 Register key, 458 Register key,
458 Register scratch, 459 Register scratch,
459 Register result, 460 Register result,
460 Label* not_fast_array, 461 Label* not_fast_array,
461 Label* out_of_range) { 462 Label* out_of_range) {
462 // Register use: 463 // Register use:
463 // receiver - holds the receiver and is unchanged. 464 // receiver - holds the receiver and is unchanged.
464 // key - holds the key and is unchanged (must be a smi). 465 // key - holds the key and is unchanged (must be a smi).
465 // Scratch registers: 466 // Scratch registers:
466 // scratch - used to hold elements of the receiver and the loaded value. 467 // scratch - used to hold elements of the receiver and the loaded value.
467 // result - holds the result on exit if the load succeeds and 468 // result - holds the result on exit if the load succeeds and
468 // we fall through. 469 // we fall through.
469 470
470 __ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset)); 471 __ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset));
471 // Check that the object is in fast mode (not dictionary). 472 if (not_fast_array != NULL) {
472 __ CheckMap(scratch, Factory::fixed_array_map(), not_fast_array, true); 473 // Check that the object is in fast mode and writable.
474 __ CheckMap(scratch, Factory::fixed_array_map(), not_fast_array, true);
475 } else {
476 __ AssertFastElements(scratch);
477 }
473 // Check that the key (index) is within bounds. 478 // Check that the key (index) is within bounds.
474 __ cmp(key, FieldOperand(scratch, FixedArray::kLengthOffset)); 479 __ cmp(key, FieldOperand(scratch, FixedArray::kLengthOffset));
475 __ j(above_equal, out_of_range); 480 __ j(above_equal, out_of_range);
476 // Fast case: Do the load. 481 // Fast case: Do the load.
477 ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0)); 482 ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0));
478 __ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize)); 483 __ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize));
479 __ cmp(Operand(scratch), Immediate(Factory::the_hole_value())); 484 __ cmp(Operand(scratch), Immediate(Factory::the_hole_value()));
480 // In case the loaded value is the_hole we have to consult GetProperty 485 // In case the loaded value is the_hole we have to consult GetProperty
481 // to ensure the prototype chain is searched. 486 // to ensure the prototype chain is searched.
482 __ j(equal, out_of_range); 487 __ j(equal, out_of_range);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 // Check that the key is a smi. 556 // Check that the key is a smi.
552 __ test(eax, Immediate(kSmiTagMask)); 557 __ test(eax, Immediate(kSmiTagMask));
553 __ j(not_zero, &check_string, not_taken); 558 __ j(not_zero, &check_string, not_taken);
554 __ bind(&index_smi); 559 __ bind(&index_smi);
555 // Now the key is known to be a smi. This place is also jumped to from 560 // Now the key is known to be a smi. This place is also jumped to from
556 // where a numeric string is converted to a smi. 561 // where a numeric string is converted to a smi.
557 562
558 GenerateKeyedLoadReceiverCheck( 563 GenerateKeyedLoadReceiverCheck(
559 masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); 564 masm, edx, ecx, Map::kHasIndexedInterceptor, &slow);
560 565
566 // Check the "has fast elements" bit in the receiver's map which is
567 // now in ecx.
568 __ test_b(FieldOperand(ecx, Map::kBitField2Offset),
569 1 << Map::kHasFastElements);
570 __ j(zero, &check_pixel_array, not_taken);
571
561 GenerateFastArrayLoad(masm, 572 GenerateFastArrayLoad(masm,
562 edx, 573 edx,
563 eax, 574 eax,
564 ecx, 575 ecx,
565 eax, 576 eax,
566 &check_pixel_array, 577 NULL,
567 &slow); 578 &slow);
568 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1); 579 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
569 __ ret(0); 580 __ ret(0);
570 581
571 __ bind(&check_pixel_array); 582 __ bind(&check_pixel_array);
572 // Check whether the elements is a pixel array. 583 // Check whether the elements is a pixel array.
573 // edx: receiver 584 // edx: receiver
574 // eax: key 585 // eax: key
575 // ecx: elements 586 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
576 __ mov(ebx, eax); 587 __ mov(ebx, eax);
577 __ SmiUntag(ebx); 588 __ SmiUntag(ebx);
578 __ CheckMap(ecx, Factory::pixel_array_map(), &check_number_dictionary, true); 589 __ CheckMap(ecx, Factory::pixel_array_map(), &check_number_dictionary, true);
579 __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset)); 590 __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset));
580 __ j(above_equal, &slow); 591 __ j(above_equal, &slow);
581 __ mov(eax, FieldOperand(ecx, PixelArray::kExternalPointerOffset)); 592 __ mov(eax, FieldOperand(ecx, PixelArray::kExternalPointerOffset));
582 __ movzx_b(eax, Operand(eax, ebx, times_1, 0)); 593 __ movzx_b(eax, Operand(eax, ebx, times_1, 0));
583 __ SmiTag(eax); 594 __ SmiTag(eax);
584 __ ret(0); 595 __ ret(0);
585 596
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 __ j(equal, &array); 971 __ j(equal, &array);
961 // Check that the object is some kind of JS object. 972 // Check that the object is some kind of JS object.
962 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); 973 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
963 __ j(below, &slow, not_taken); 974 __ j(below, &slow, not_taken);
964 975
965 // Object case: Check key against length in the elements array. 976 // Object case: Check key against length in the elements array.
966 // eax: value 977 // eax: value
967 // edx: JSObject 978 // edx: JSObject
968 // ecx: key (a smi) 979 // ecx: key (a smi)
969 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 980 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
970 // Check that the object is in fast mode (not dictionary). 981 // Check that the object is in fast mode and writable.
971 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true); 982 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true);
972 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); 983 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
973 __ j(below, &fast, taken); 984 __ j(below, &fast, taken);
974 985
975 // Slow case: call runtime. 986 // Slow case: call runtime.
976 __ bind(&slow); 987 __ bind(&slow);
977 GenerateRuntimeSetProperty(masm); 988 GenerateRuntimeSetProperty(masm);
978 989
979 // Check whether the elements is a pixel array. 990 // Check whether the elements is a pixel array.
980 __ bind(&check_pixel_array); 991 __ bind(&check_pixel_array);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 // flags: compare (ecx, edx.length()) 1027 // flags: compare (ecx, edx.length())
1017 __ j(not_equal, &slow, not_taken); // do not leave holes in the array 1028 __ j(not_equal, &slow, not_taken); // do not leave holes in the array
1018 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); 1029 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
1019 __ j(above_equal, &slow, not_taken); 1030 __ j(above_equal, &slow, not_taken);
1020 // Add 1 to receiver->length, and go to fast array write. 1031 // Add 1 to receiver->length, and go to fast array write.
1021 __ add(FieldOperand(edx, JSArray::kLengthOffset), 1032 __ add(FieldOperand(edx, JSArray::kLengthOffset),
1022 Immediate(Smi::FromInt(1))); 1033 Immediate(Smi::FromInt(1)));
1023 __ jmp(&fast); 1034 __ jmp(&fast);
1024 1035
1025 // Array case: Get the length and the elements array from the JS 1036 // Array case: Get the length and the elements array from the JS
1026 // array. Check that the array is in fast mode; if it is the 1037 // array. Check that the array is in fast mode (and writable); if it
1027 // length is always a smi. 1038 // is the length is always a smi.
1028 __ bind(&array); 1039 __ bind(&array);
1029 // eax: value 1040 // eax: value
1030 // edx: receiver, a JSArray 1041 // edx: receiver, a JSArray
1031 // ecx: key, a smi. 1042 // ecx: key, a smi.
1032 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 1043 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
1033 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true); 1044 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true);
1034 1045
1035 // Check the key against the length in the array, compute the 1046 // Check the key against the length in the array, compute the
1036 // address to store into and fall through to fast case. 1047 // address to store into and fall through to fast case.
1037 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. 1048 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 1876
1866 // Check that the receiver isn't a smi. 1877 // Check that the receiver isn't a smi.
1867 __ test(receiver, Immediate(kSmiTagMask)); 1878 __ test(receiver, Immediate(kSmiTagMask));
1868 __ j(zero, &miss, not_taken); 1879 __ j(zero, &miss, not_taken);
1869 1880
1870 // Check that the object is a JS array. 1881 // Check that the object is a JS array.
1871 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); 1882 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
1872 __ j(not_equal, &miss, not_taken); 1883 __ j(not_equal, &miss, not_taken);
1873 1884
1874 // Check that elements are FixedArray. 1885 // Check that elements are FixedArray.
1886 // We rely on StoreIC_ArrayLength below to deal with all types of
1887 // fast elements (including COW).
1875 __ mov(scratch, FieldOperand(receiver, JSArray::kElementsOffset)); 1888 __ mov(scratch, FieldOperand(receiver, JSArray::kElementsOffset));
1876 __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch); 1889 __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch);
1877 __ j(not_equal, &miss, not_taken); 1890 __ j(not_equal, &miss, not_taken);
1878 1891
1879 // Check that value is a smi. 1892 // Check that value is a smi.
1880 __ test(value, Immediate(kSmiTagMask)); 1893 __ test(value, Immediate(kSmiTagMask));
1881 __ j(not_zero, &miss, not_taken); 1894 __ j(not_zero, &miss, not_taken);
1882 1895
1883 // Prepare tail call to StoreIC_ArrayLength. 1896 // Prepare tail call to StoreIC_ArrayLength.
1884 __ pop(scratch); 1897 __ pop(scratch);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); 1978 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1966 __ TailCallExternalReference(ref, 3, 1); 1979 __ TailCallExternalReference(ref, 3, 1);
1967 } 1980 }
1968 1981
1969 #undef __ 1982 #undef __
1970 1983
1971 1984
1972 } } // namespace v8::internal 1985 } } // namespace v8::internal
1973 1986
1974 #endif // V8_TARGET_ARCH_IA32 1987 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698