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

Unified Diff: src/a64/stub-cache-a64.cc

Issue 148573005: A64: Synchronize with r16249. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/a64/lithium-codegen-a64.cc ('k') | src/accessors.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/a64/stub-cache-a64.cc
diff --git a/src/a64/stub-cache-a64.cc b/src/a64/stub-cache-a64.cc
index 203fcc3715e0621f212cc74e3d0be0ca1dc947b3..2cdc1b97fc5da7760111ece4f55a041e8907f54d 100644
--- a/src/a64/stub-cache-a64.cc
+++ b/src/a64/stub-cache-a64.cc
@@ -170,39 +170,6 @@ static void ProbeTable(Isolate* isolate,
}
-// Check if key is a smi or can be converted into a smi.
-// If not jump on 'fail' and fall-through otherwise.
-static void GenerateSmiKeyCheck(MacroAssembler* masm,
- Register key,
- Register scratch0,
- FPRegister double_scratch0,
- FPRegister double_scratch1,
- Label* fail) {
- Label key_ok;
- __ JumpIfSmi(key, &key_ok);
-
- // The key is not a smi. Check for a smi inside a heap number.
- __ CheckMap(key,
- scratch0,
- masm->isolate()->factory()->heap_number_map(),
- fail,
- DONT_DO_SMI_CHECK);
-
- __ Ldr(scratch0, FieldMemOperand(key, HeapNumber::kValueOffset));
- __ Fmov(double_scratch0, scratch0);
- __ TryConvertDoubleToInt32(scratch0.W(),
- double_scratch0,
- double_scratch1,
- NULL,
- fail);
- // The double value has been coverted to a 32-bit signed integer.
- // We just need to tag it.
- __ SmiTag(key, scratch0);
-
- __ Bind(&key_ok);
-}
-
-
void StubCache::GenerateProbe(MacroAssembler* masm,
Code::Flags flags,
Register receiver,
@@ -3287,474 +3254,6 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
}
-static void GenerateStoreSmiToExternalArray(
- MacroAssembler* masm,
- ElementsKind elements_kind,
- Register value,
- Register key_raw, // Untagged 'key'.
- Register elements_ext, // elements[ExternalArray::kExternalPointerOffset]
- Register scratch,
- FPRegister double_scratch) {
- // Convert the smi in value (x0) to the specified element kind, and store it
- // in the external array. No input registers are clobbered by this helper,
- // other than the scratch registers.
-
- ASSERT(!AreAliased(value, key_raw, elements_ext, scratch, double_scratch));
-
- switch (elements_kind) {
- case EXTERNAL_PIXEL_ELEMENTS:
- __ SmiUntag(scratch, value);
- // Clamp the value to [0..255].
- __ Cmp(scratch, Operand(scratch, UXTB));
- // If scratch < scratch & 0xff, it must be < 0, so saturate to 0.
- __ CzeroX(scratch, lt);
- // If scratch > scratch & 0xff, it must be > 255, so saturate to 255.
- // This actually generates ~0, but it doesn't matter if we use strb.
- __ Csinv(scratch, scratch, xzr, le);
- __ Strb(scratch.W(), MemOperand(elements_ext, key_raw));
- break;
- case EXTERNAL_BYTE_ELEMENTS:
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- __ SmiUntag(scratch, value);
- __ Strb(scratch.W(), MemOperand(elements_ext, key_raw));
- break;
- case EXTERNAL_SHORT_ELEMENTS:
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ SmiUntag(scratch, value);
- __ Strh(scratch.W(),
- MemOperand(elements_ext, key_raw, LSL, kHalfWordSizeInBytesLog2));
- break;
- case EXTERNAL_INT_ELEMENTS:
- case EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ SmiUntag(scratch, value);
- __ Str(scratch.W(),
- MemOperand(elements_ext, key_raw, LSL, kWordSizeInBytesLog2));
- break;
- case EXTERNAL_FLOAT_ELEMENTS:
- __ SmiUntagToFloat(double_scratch.S(), value);
- __ Str(double_scratch.S(),
- MemOperand(elements_ext, key_raw, LSL, kSRegSizeInBytesLog2));
- break;
- case EXTERNAL_DOUBLE_ELEMENTS:
- __ SmiUntagToDouble(double_scratch, value);
- __ Str(double_scratch,
- MemOperand(elements_ext, key_raw, LSL, kDRegSizeInBytesLog2));
- break;
- case FAST_ELEMENTS:
- case FAST_SMI_ELEMENTS:
- case FAST_DOUBLE_ELEMENTS:
- case FAST_HOLEY_ELEMENTS:
- case FAST_HOLEY_SMI_ELEMENTS:
- case FAST_HOLEY_DOUBLE_ELEMENTS:
- case DICTIONARY_ELEMENTS:
- case NON_STRICT_ARGUMENTS_ELEMENTS:
- UNREACHABLE();
- break;
- }
-}
-
-
-static void GenerateStoreHeapNumberToExternalArray(
- MacroAssembler* masm,
- ElementsKind elements_kind,
- Register value,
- Register key_raw, // Untagged 'key'.
- Register elements_ext, // elements[ExternalArray::kExternalPointerOffset]
- Register scratch,
- FPRegister double_scratch1,
- FPRegister double_scratch2) {
- // Convert the heap number in value (x0) to the specified element kind, and
- // store it in the external array. No input registers are clobbered by this
- // helper, other than the scratch registers.
-
- ASSERT(!AreAliased(value, key_raw, elements_ext, scratch,
- double_scratch1, double_scratch2));
-
- FPRegister value_d = double_scratch1;
- __ Ldr(value_d, FieldMemOperand(value, HeapNumber::kValueOffset));
-
- // Convert the (double) input to an integral type.
- switch (elements_kind) {
- case EXTERNAL_FLOAT_ELEMENTS:
- __ Fcvt(s16, value_d);
- __ Str(s16, MemOperand(elements_ext, key_raw, LSL, 2));
- break;
- case EXTERNAL_DOUBLE_ELEMENTS:
- __ Str(value_d, MemOperand(elements_ext, key_raw, LSL, 3));
- break;
- case EXTERNAL_PIXEL_ELEMENTS:
- // This conversion follows the WebIDL "[Clamp]" rules:
- // - Inputs lower than 0 (including -infinity) produce 0.
- // - Inputs higher than 255 (including +infinity) produce 255.
- // Also, it seems that PIXEL types use round-to-nearest rather than
- // round-towards-zero.
-
- // Squash +infinity before the conversion, since Fcvtnu will normally
- // convert it to 0.
- __ Fmov(double_scratch2, 255);
- __ Fmin(double_scratch2, double_scratch2, value_d);
-
- // Convert double to unsigned integer. Values less than zero become zero.
- // Values greater than 255 have already been clamped to 255.
- __ Fcvtnu(scratch.W(), double_scratch2);
-
- __ Strb(scratch.W(), MemOperand(elements_ext, key_raw));
- break;
- case EXTERNAL_BYTE_ELEMENTS:
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- __ ECMA262ToInt32(scratch, value_d, x11, x12, MacroAssembler::INT32_IN_W);
- __ Strb(scratch.W(), MemOperand(elements_ext, key_raw));
- break;
- case EXTERNAL_SHORT_ELEMENTS:
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ ECMA262ToInt32(scratch, value_d, x11, x12, MacroAssembler::INT32_IN_W);
- __ Strh(scratch.W(),
- MemOperand(elements_ext, key_raw, LSL, kHalfWordSizeInBytesLog2));
- break;
- case EXTERNAL_INT_ELEMENTS:
- case EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ ECMA262ToInt32(scratch, value_d, x11, x12, MacroAssembler::INT32_IN_W);
- __ Str(scratch.W(),
- MemOperand(elements_ext, key_raw, LSL, kWordSizeInBytesLog2));
- break;
- case FAST_ELEMENTS:
- case FAST_SMI_ELEMENTS:
- case FAST_DOUBLE_ELEMENTS:
- case FAST_HOLEY_ELEMENTS:
- case FAST_HOLEY_SMI_ELEMENTS:
- case FAST_HOLEY_DOUBLE_ELEMENTS:
- case DICTIONARY_ELEMENTS:
- case NON_STRICT_ARGUMENTS_ELEMENTS:
- UNREACHABLE();
- break;
- }
-}
-
-
-void KeyedStoreStubCompiler::GenerateStoreExternalArray(
- MacroAssembler* masm,
- ElementsKind elements_kind) {
- // ---------- S t a t e --------------
- // -- lr : return address
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -----------------------------------
- Label slow, check_heap_number, miss_force_generic;
-
- // Register usage.
- Register value = x0;
- Register key = x1;
- Register receiver = x2;
-
- // This stub is meant to be tail-jumped to, the receiver must already
- // have been verified by the caller to not be a smi.
- if (__ emit_debug_code()) {
- __ AssertNotSmi(receiver);
- }
-
- // Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key, x10, d16, d17, &miss_force_generic);
-
- Register elements = x3;
- __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
-
- Register key_raw = x4;
- __ SmiUntag(key_raw, key);
-
- // Check that the key is within bounds. An unsigned comparison catches both
- // negative and out-of-bound indexes.
- __ Ldrsw(x10,
- UntagSmiFieldMemOperand(elements, ExternalArray::kLengthOffset));
- __ Cmp(key_raw.W(), w10);
- __ B(&miss_force_generic, hs);
-
- // Get the externally-stored elements.
- Register elements_ext = x5;
- __ Ldr(elements_ext,
- FieldMemOperand(elements, ExternalArray::kExternalPointerOffset));
-
- // x0: value
- // x1: key
- // x2: receiver
- // x3: elements
- // x4: key_raw Untagged 'key'.
- // x5: elements_ext From elements[ExternalArray::kExternalPointerOffset].
-
- // Handle both smis and HeapNumbers in the fast path. Go to the
- // runtime for all other kinds of values.
- __ JumpIfNotSmi(value, &check_heap_number);
-
- GenerateStoreSmiToExternalArray(
- masm, elements_kind, value, key_raw, elements_ext, x10, d16);
- // Entry registers are intact and x0 holds 'value', which is the return value.
- __ Ret();
-
- __ Bind(&check_heap_number);
- // Convert the double at 'value' to the specified element kind.
- //
- // x0: value
- // x1: key
- // x2: receiver
- // x3: elements
- // x4: key_raw Untagged 'key'.
- // x5: elements_ext From elements[ExternalArray::kExternalPointerOffset].
- __ JumpIfNotObjectType(value, x10, x11, HEAP_NUMBER_TYPE, &slow);
-
- GenerateStoreHeapNumberToExternalArray(
- masm, elements_kind, value, key_raw, elements_ext, x10, d16, d17);
- // Entry registers are intact and x0 holds 'value', which is the return value.
- __ Ret();
-
- __ Bind(&slow);
- // ---------- S t a t e --------------
- // -- lr : return address
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -----------------------------------
- __ IncrementCounter(
- masm->isolate()->counters()->keyed_load_external_array_slow(),
- 1, x10, x11);
-
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
-
- // Miss case, call the runtime.
- __ Bind(&miss_force_generic);
- // ---------- S t a t e --------------
- // -- lr : return address
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -----------------------------------
-
- TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
-}
-
-
-static void GenerateStoreFastSmiOrDoubleElement(
- MacroAssembler* masm,
- bool is_js_array,
- ElementsKind elements_kind,
- KeyedAccessStoreMode store_mode,
- bool store_double) {
- Label miss_force_generic, transition_elements_kind, grow, slow;
- Label finish_store, check_capacity;
-
- Register value = x0;
- Register key = x1;
- Register receiver = x2;
-
- // This stub is meant to be tail-jumped to, the receiver must already
- // have been verified by the caller to not be a smi.
- if (__ emit_debug_code()) {
- __ AssertNotSmi(receiver);
- }
-
- // Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key, x10, d16, d17, &miss_force_generic);
-
- if (!store_double && IsFastSmiElementsKind(elements_kind)) {
- __ JumpIfNotSmi(value, &transition_elements_kind);
- }
-
- Register elements = x3;
- __ Ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
-
- // Check that the key is within bounds.
- Register length = x4;
- if (is_js_array) {
- __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
- } else {
- __ Ldr(length, FieldMemOperand(elements, FixedArray::kLengthOffset));
- }
- // Compare smis. An unsigned comparison catches both negative and out-of-bound
- // indexes.
- __ Cmp(key, length);
- if (is_js_array && IsGrowStoreMode(store_mode)) {
- // We can handle the case where the array needs to grow by a single element
- // without falling back to run-time.
- __ B(&grow, eq);
- }
- // Fall back to the run-time if the key is out of bounds.
- __ B(&miss_force_generic, hs);
-
- if (store_double) {
- __ Bind(&finish_store);
- __ StoreNumberToDoubleElements(value, key, elements, x10, d16, d17,
- &transition_elements_kind);
- } else {
- // Make sure elements is a fast element array, not 'cow'.
- // TODO(jbramley): Why is this only done when storing a smi?
- __ CheckMap(elements, x10,
- Heap::kFixedArrayMapRootIndex,
- &miss_force_generic,
- DONT_DO_SMI_CHECK);
-
- __ Bind(&finish_store);
-
- STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2);
- __ Add(x10, elements, FixedArray::kHeaderSize - kHeapObjectTag);
- __ Add(x10, x10, Operand::UntagSmiAndScale(key, kPointerSizeLog2));
- __ Str(value, MemOperand(x10));
- if (!IsFastSmiElementsKind(elements_kind)) {
- ASSERT(IsFastObjectElementsKind(elements_kind));
- __ Mov(receiver, value);
- __ RecordWrite(elements, // Object.
- x10, // Address.
- receiver, // Value.
- kLRHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- INLINE_SMI_CHECK,
- EXPECT_PREGENERATED);
- }
- // Value (x0) is preserved.
- }
- __ Ret();
-
- __ Bind(&miss_force_generic);
- KeyedStoreStubCompiler::TailCallBuiltin(
- masm, Builtins::kKeyedStoreIC_MissForceGeneric);
-
- __ Bind(&transition_elements_kind);
- KeyedStoreStubCompiler::TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
-
- if (is_js_array && IsGrowStoreMode(store_mode)) {
- // Grow a JSArray by a single element.
- __ Bind(&grow);
-
- // x1: key
- // x2: receiver
- // x3: elements From receiver[JSObject::kElementsOffset].
- // x4: length From receiver[JSArray::kLengthOffset].
-
- if (__ emit_debug_code()) {
- // Check that 'elements' and 'length' are pre-loaded.
- __ Ldr(x10, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ Cmp(x10, x3);
- __ Ldr(x11, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Ccmp(x11, x4, NoFlag, eq);
-
- // Check that the key is equal to length, so we need to extend the array
- // by one element.
- __ Ccmp(x1, x4, NoFlag, eq);
-
- __ Check(eq, kPreconditionsWereNotMet);
- }
-
- __ JumpIfNotRoot(elements, Heap::kEmptyFixedArrayRootIndex,
- &check_capacity);
-
- // The array is currently empty, so allocate a new backing store.
- int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
- __ Allocate(size, elements, x10, x11, &slow, TAG_OBJECT);
- Heap::RootListIndex root_index = store_double
- ? Heap::kFixedDoubleArrayMapRootIndex
- : Heap::kFixedArrayMapRootIndex;
- __ LoadRoot(x12, root_index);
- __ Str(x12, FieldMemOperand(elements, JSObject::kMapOffset));
- __ Mov(x13, Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements)));
- __ Str(x13, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Store the element at index zero, and fill the rest with the hole value.
- if (store_double) {
- __ StoreNumberToDoubleElements(value,
- key,
- elements,
- x10,
- d16,
- d17,
- &transition_elements_kind);
- __ Fmov(d16, rawbits_to_double(kHoleNanInt64));
- for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) {
- __ Str(d16, FieldMemOperand(elements,
- FixedDoubleArray::OffsetOfElementAt(i)));
- }
- } else {
- __ Str(value, FieldMemOperand(elements, FixedArray::SizeFor(0)));
- __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
- for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) {
- __ Str(x10, FieldMemOperand(elements,
- FixedArray::OffsetOfElementAt(i)));
- }
- }
-
- // Install the new backing store in the JSArray.
- __ Str(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ RecordWriteField(receiver, JSObject::kElementsOffset, elements,
- x10, kLRHasNotBeenSaved, kDontSaveFPRegs,
- EMIT_REMEMBERED_SET, OMIT_SMI_CHECK,
- EXPECT_PREGENERATED);
-
- // Increment the length of the array.
- __ Mov(length, Operand(Smi::FromInt(1)));
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Ret();
-
- __ Bind(&check_capacity);
-
- if (!store_double) {
- // Check for cow elements, in general they are not handled by this stub
- // TODO(jbramley): Why is this only done when storing a smi?
- __ CheckMap(elements, x10,
- Heap::kFixedCOWArrayMapRootIndex,
- &miss_force_generic,
- DONT_DO_SMI_CHECK);
- }
-
- // See if there are any free preallocated slots. If not, defer to the
- // runtime to extend the backing store.
- __ Ldr(x10, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ Cmp(length, x10);
- __ B(&slow, hs);
-
- // Grow the array and finish the store.
- __ Add(length, length, Operand(Smi::FromInt(1)));
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ B(&finish_store);
-
- __ Bind(&slow);
- KeyedStoreStubCompiler::TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
- }
-}
-
-
-void KeyedStoreStubCompiler::GenerateStoreFastElement(
- MacroAssembler* masm,
- bool is_js_array,
- ElementsKind elements_kind,
- KeyedAccessStoreMode store_mode) {
-
- // ----------- S t a t e -------------
- // -- lr : return address
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -----------------------------------
-
- GenerateStoreFastSmiOrDoubleElement(masm, is_js_array, elements_kind,
- store_mode, false);
-}
-
-
-void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
- MacroAssembler* masm,
- bool is_js_array,
- KeyedAccessStoreMode store_mode) {
-
- // ----------- S t a t e -------------
- // -- lr : return address
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // ----------- S t a t e -------------
-
- GenerateStoreFastSmiOrDoubleElement(masm, is_js_array, FAST_DOUBLE_ELEMENTS,
- store_mode, true);
-}
-
-
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_A64
« no previous file with comments | « src/a64/lithium-codegen-a64.cc ('k') | src/accessors.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698