From: danno@chromium.org Date: Thu, 9 Jun 2011 15:19:37 +0000 (+0000) Subject: Dispatch on ElementsKind rather than ExternalArrayType when generating ICs and Cranks... X-Git-Tag: upstream/4.7.83~19186 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9f432cd1593eefe447af1fe333af7f843ca376ce;p=platform%2Fupstream%2Fv8.git Dispatch on ElementsKind rather than ExternalArrayType when generating ICs and Crankshaft code for many element operations. This is preparation to be able to share more code in the various element accessor implementations. Merge logic to maintain external array and fast element stub caches. BUG=none TEST=none Review URL: http://codereview.chromium.org/7112010 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8244 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 8ec43184c..76b30c985 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1933,13 +1933,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( HLoadKeyedSpecializedArrayElement* instr) { - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); Representation representation(instr->representation()); ASSERT( - (representation.IsInteger32() && (array_type != kExternalFloatArray && - array_type != kExternalDoubleArray)) || - (representation.IsDouble() && (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray))); + (representation.IsInteger32() && + (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (representation.IsDouble() && + ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); @@ -1948,7 +1950,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* load_instr = DefineAsRegister(result); // An unsigned int array load might overflow and cause a deopt, make sure it // has an environment. - return (array_type == kExternalUnsignedIntArray) ? + return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ? AssignEnvironment(load_instr) : load_instr; } @@ -1985,18 +1987,21 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( HStoreKeyedSpecializedArrayElement* instr) { Representation representation(instr->value()->representation()); - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); ASSERT( - (representation.IsInteger32() && (array_type != kExternalFloatArray && - array_type != kExternalDoubleArray)) || - (representation.IsDouble() && (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray))); + (representation.IsInteger32() && + (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (representation.IsDouble() && + ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); - bool val_is_temp_register = array_type == kExternalPixelArray || - array_type == kExternalFloatArray; + bool val_is_temp_register = + elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS || + elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS; LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) : UseRegister(instr->value()); diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 43738d7c3..9ec8d846c 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -1297,8 +1297,8 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } - ExternalArrayType array_type() const { - return hydrogen()->array_type(); + JSObject::ElementsKind elements_kind() const { + return hydrogen()->elements_kind(); } }; @@ -1779,8 +1779,8 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - ExternalArrayType array_type() const { - return hydrogen()->array_type(); + JSObject::ElementsKind elements_kind() const { + return hydrogen()->elements_kind(); } }; diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index ab6cd028c..fe29097cd 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -2611,7 +2611,7 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( LLoadKeyedSpecializedArrayElement* instr) { Register external_pointer = ToRegister(instr->external_pointer()); Register key = no_reg; - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); bool key_is_constant = instr->key()->IsConstantOperand(); int constant_key = 0; if (key_is_constant) { @@ -2622,18 +2622,19 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( } else { key = ToRegister(instr->key()); } - int shift_size = ExternalArrayTypeToShiftSize(array_type); + int shift_size = ElementsKindToShiftSize(elements_kind); - if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || + elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { CpuFeatures::Scope scope(VFP3); DwVfpRegister result(ToDoubleRegister(instr->result())); Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) : Operand(key, LSL, shift_size)); __ add(scratch0(), external_pointer, operand); - if (array_type == kExternalFloatArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { __ vldr(result.low(), scratch0(), 0); __ vcvt_f64_f32(result, result.low()); - } else { // i.e. array_type == kExternalDoubleArray + } else { // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS __ vldr(result, scratch0(), 0); } } else { @@ -2641,24 +2642,24 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( MemOperand mem_operand(key_is_constant ? MemOperand(external_pointer, constant_key * (1 << shift_size)) : MemOperand(external_pointer, key, LSL, shift_size)); - switch (array_type) { - case kExternalByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: __ ldrsb(result, mem_operand); break; - case kExternalUnsignedByteArray: - case kExternalPixelArray: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ ldrb(result, mem_operand); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: __ ldrsh(result, mem_operand); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ ldrh(result, mem_operand); break; - case kExternalIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: __ ldr(result, mem_operand); break; - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ ldr(result, mem_operand); __ cmp(result, Operand(0x80000000)); // TODO(danno): we could be more clever here, perhaps having a special @@ -2666,8 +2667,11 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( // happens, and generate code that returns a double rather than int. DeoptimizeIf(cs, instr->environment()); break; - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } @@ -3423,7 +3427,7 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( Register external_pointer = ToRegister(instr->external_pointer()); Register key = no_reg; - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); bool key_is_constant = instr->key()->IsConstantOperand(); int constant_key = 0; if (key_is_constant) { @@ -3434,18 +3438,19 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( } else { key = ToRegister(instr->key()); } - int shift_size = ExternalArrayTypeToShiftSize(array_type); + int shift_size = ElementsKindToShiftSize(elements_kind); - if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || + elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { CpuFeatures::Scope scope(VFP3); DwVfpRegister value(ToDoubleRegister(instr->value())); Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) : Operand(key, LSL, shift_size)); __ add(scratch0(), external_pointer, operand); - if (array_type == kExternalFloatArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { __ vcvt_f32_f64(double_scratch0().low(), value); __ vstr(double_scratch0().low(), scratch0(), 0); - } else { // i.e. array_type == kExternalDoubleArray + } else { // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS __ vstr(value, scratch0(), 0); } } else { @@ -3453,22 +3458,25 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( MemOperand mem_operand(key_is_constant ? MemOperand(external_pointer, constant_key * (1 << shift_size)) : MemOperand(external_pointer, key, LSL, shift_size)); - switch (array_type) { - case kExternalPixelArray: - case kExternalByteArray: - case kExternalUnsignedByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(value, mem_operand); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(value, mem_operand); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(value, mem_operand); break; - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index cc7de05dc..7fd5fa71f 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -3115,13 +3115,20 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { } -MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { +MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { // ----------- S t a t e ------------- // -- lr : return address // -- r0 : key // -- r1 : receiver // ----------------------------------- - MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode(); + MaybeObject* maybe_stub; + if (receiver_map->has_fast_elements()) { + maybe_stub = KeyedLoadFastElementStub().TryGetCode(); + } else { + ASSERT(receiver_map->has_external_array_elements()); + JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + maybe_stub = KeyedLoadExternalArrayStub(elements_kind).TryGetCode(); + } Code* stub; if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(r1, @@ -3206,7 +3213,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, } -MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( +MaybeObject* KeyedStoreStubCompiler::CompileStoreElement( Map* receiver_map) { // ----------- S t a t e ------------- // -- r0 : value @@ -3215,9 +3222,15 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( // -- lr : return address // -- r3 : scratch // ----------------------------------- - bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; - MaybeObject* maybe_stub = - KeyedStoreFastElementStub(is_js_array).TryGetCode(); + MaybeObject* maybe_stub; + if (receiver_map->has_fast_elements()) { + bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; + maybe_stub = KeyedStoreFastElementStub(is_js_array).TryGetCode(); + } else { + ASSERT(receiver_map->has_external_array_elements()); + JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + maybe_stub = KeyedStoreExternalArrayStub(elements_kind).TryGetCode(); + } Code* stub; if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(r2, @@ -3410,82 +3423,38 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { } -MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad( - JSObject*receiver, ExternalArrayType array_type) { - // ----------- S t a t e ------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- - MaybeObject* maybe_stub = - KeyedLoadExternalArrayStub(array_type).TryGetCode(); - Code* stub; - if (!maybe_stub->To(&stub)) return maybe_stub; - __ DispatchMap(r1, - r2, - Handle(receiver->map()), - Handle(stub), - DO_SMI_CHECK); - - Handle ic = isolate()->builtins()->KeyedLoadIC_Miss(); - __ Jump(ic, RelocInfo::CODE_TARGET); - - // Return the generated code. - return GetCode(); -} - - -MaybeObject* ExternalArrayStoreStubCompiler::CompileStore( - JSObject* receiver, ExternalArrayType array_type) { - // ----------- S t a t e ------------- - // -- r0 : value - // -- r1 : name - // -- r2 : receiver - // -- lr : return address - // ----------------------------------- - MaybeObject* maybe_stub = - KeyedStoreExternalArrayStub(array_type).TryGetCode(); - Code* stub; - if (!maybe_stub->To(&stub)) return maybe_stub; - __ DispatchMap(r2, - r3, - Handle(receiver->map()), - Handle(stub), - DO_SMI_CHECK); - - Handle ic = isolate()->builtins()->KeyedStoreIC_Miss(); - __ Jump(ic, RelocInfo::CODE_TARGET); - - return GetCode(); -} - - #undef __ #define __ ACCESS_MASM(masm) -static bool IsElementTypeSigned(ExternalArrayType array_type) { - switch (array_type) { - case kExternalByteArray: - case kExternalShortArray: - case kExternalIntArray: +static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) { + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_INT_ELEMENTS: return true; - case kExternalUnsignedByteArray: - case kExternalUnsignedShortArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: return false; - default: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); return false; } + return false; } void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, - ExternalArrayType array_type) { + JSObject::ElementsKind elements_kind) { // ---------- S t a t e -------------- // -- lr : return address // -- r0 : key @@ -3519,25 +3488,25 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( ASSERT((kSmiTag == 0) && (kSmiTagSize == 1)); Register value = r2; - switch (array_type) { - case kExternalByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: __ ldrsb(value, MemOperand(r3, key, LSR, 1)); break; - case kExternalPixelArray: - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ ldrb(value, MemOperand(r3, key, LSR, 1)); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: __ ldrsh(value, MemOperand(r3, key, LSL, 0)); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ ldrh(value, MemOperand(r3, key, LSL, 0)); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ ldr(value, MemOperand(r3, key, LSL, 1)); break; - case kExternalFloatArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); __ add(r2, r3, Operand(key, LSL, 1)); @@ -3546,7 +3515,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ ldr(value, MemOperand(r3, key, LSL, 1)); } break; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); __ add(r2, r3, Operand(key, LSL, 2)); @@ -3558,7 +3527,9 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ ldr(r3, MemOperand(r4, Register::kSizeInBytes)); } break; - default: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } @@ -3572,7 +3543,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // d0: value (if VFP3 is supported) // r2/r3: value (if VFP3 is not supported) - if (array_type == kExternalIntArray) { + if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { // For the Int and UnsignedInt array types, we need to see whether // the value can be represented in a Smi. If not, we need to convert // it to a HeapNumber. @@ -3616,7 +3587,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); __ Ret(); } - } else if (array_type == kExternalUnsignedIntArray) { + } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { // The test is different for unsigned int values. Since we need // the value to be in the range of a positive smi, we can't // handle either of the top two bits being set in the value. @@ -3681,7 +3652,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(r0, r4); __ Ret(); } - } else if (array_type == kExternalFloatArray) { + } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. if (CpuFeatures::IsSupported(VFP3)) { @@ -3751,7 +3722,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(r0, r3); __ Ret(); } - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); // Allocate a HeapNumber for the result. Don't use r0 and r1 as @@ -3808,7 +3779,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, - ExternalArrayType array_type) { + JSObject::ElementsKind elements_kind) { // ---------- S t a t e -------------- // -- r0 : value // -- r1 : key @@ -3842,7 +3813,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // runtime for all other kinds of values. // r3: external array. // r4: key (integer). - if (array_type == kExternalPixelArray) { + if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { // Double to pixel conversion is only implemented in the runtime for now. __ JumpIfNotSmi(value, &slow); } else { @@ -3854,29 +3825,29 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // r3: base pointer of external storage. // r4: key (integer). // r5: value (integer). - switch (array_type) { - case kExternalPixelArray: + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: // Clamp the value to [0..255]. __ Usat(r5, 8, Operand(r5)); __ strb(r5, MemOperand(r3, r4, LSL, 0)); break; - case kExternalByteArray: - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(r5, MemOperand(r3, r4, LSL, 0)); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(r5, MemOperand(r3, r4, LSL, 1)); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(r5, MemOperand(r3, r4, LSL, 2)); break; - case kExternalFloatArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: // Perform int-to-float conversion and store to memory. StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); break; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: __ add(r3, r3, Operand(r4, LSL, 3)); // r3: effective address of the double element FloatingPointHelper::Destination destination; @@ -3897,7 +3868,9 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ str(r7, MemOperand(r3, Register::kSizeInBytes)); } break; - default: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } @@ -3905,7 +3878,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // Entry registers are intact, r0 holds the value which is the return value. __ Ret(); - if (array_type != kExternalPixelArray) { + if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { // r3: external array. // r4: index (integer). __ bind(&check_heap_number); @@ -3923,7 +3896,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); - if (array_type == kExternalFloatArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { // vldr requires offset to be a multiple of 4 so we can not // include -kHeapObjectTag into it. __ sub(r5, r0, Operand(kHeapObjectTag)); @@ -3931,7 +3904,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ add(r5, r3, Operand(r4, LSL, 2)); __ vcvt_f32_f64(s0, d0); __ vstr(s0, r5, 0); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ sub(r5, r0, Operand(kHeapObjectTag)); __ vldr(d0, r5, HeapNumber::kValueOffset); __ add(r5, r3, Operand(r4, LSL, 3)); @@ -3943,20 +3916,25 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ vldr(d0, r5, HeapNumber::kValueOffset); __ EmitECMATruncate(r5, d0, s2, r6, r7, r9); - switch (array_type) { - case kExternalByteArray: - case kExternalUnsignedByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(r5, MemOperand(r3, r4, LSL, 0)); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(r5, MemOperand(r3, r4, LSL, 1)); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(r5, MemOperand(r3, r4, LSL, 2)); break; - default: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } @@ -3970,7 +3948,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset)); __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset)); - if (array_type == kExternalFloatArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { Label done, nan_or_infinity_or_zero; static const int kMantissaInHiWordShift = kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; @@ -4022,14 +4000,14 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift)); __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift)); __ b(&done); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ add(r7, r3, Operand(r4, LSL, 3)); // r7: effective address of destination element. __ str(r6, MemOperand(r7, 0)); __ str(r5, MemOperand(r7, Register::kSizeInBytes)); __ Ret(); } else { - bool is_signed_type = IsElementTypeSigned(array_type); + bool is_signed_type = IsElementTypeSigned(elements_kind); int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; @@ -4076,20 +4054,25 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne); __ bind(&done); - switch (array_type) { - case kExternalByteArray: - case kExternalUnsignedByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(r5, MemOperand(r3, r4, LSL, 0)); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(r5, MemOperand(r3, r4, LSL, 1)); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(r5, MemOperand(r3, r4, LSL, 2)); break; - default: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } diff --git a/src/ast.cc b/src/ast.cc index 523b6eee3..a120828ee 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -607,9 +607,6 @@ void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { is_string_access_ = true; } else if (is_monomorphic_) { monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this); - if (monomorphic_receiver_type_->has_external_array_elements()) { - set_external_array_type(oracle->GetKeyedLoadExternalArrayType(this)); - } } } @@ -627,9 +624,6 @@ void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) { } else if (is_monomorphic_) { // Record receiver type for monomorphic keyed loads. monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this); - if (monomorphic_receiver_type_->has_external_array_elements()) { - set_external_array_type(oracle->GetKeyedStoreExternalArrayType(this)); - } } } @@ -639,9 +633,6 @@ void CountOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) { if (is_monomorphic_) { // Record receiver type for monomorphic keyed loads. monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this); - if (monomorphic_receiver_type_->has_external_array_elements()) { - set_external_array_type(oracle->GetKeyedStoreExternalArrayType(this)); - } } } diff --git a/src/ast.h b/src/ast.h index 92b6687fd..12b20244b 100644 --- a/src/ast.h +++ b/src/ast.h @@ -261,17 +261,9 @@ class Expression: public AstNode { return Handle(); } - ExternalArrayType external_array_type() const { - return external_array_type_; - } - void set_external_array_type(ExternalArrayType array_type) { - external_array_type_ = array_type; - } - unsigned id() const { return id_; } private: - ExternalArrayType external_array_type_; unsigned id_; }; diff --git a/src/code-stubs.cc b/src/code-stubs.cc index d12def85e..db57280f4 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -255,12 +255,12 @@ void KeyedStoreFastElementStub::Generate(MacroAssembler* masm) { void KeyedLoadExternalArrayStub::Generate(MacroAssembler* masm) { - KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, array_type_); + KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_); } void KeyedStoreExternalArrayStub::Generate(MacroAssembler* masm) { - KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, array_type_); + KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_); } diff --git a/src/code-stubs.h b/src/code-stubs.h index 087d29e30..6a7b6616d 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -975,11 +975,11 @@ class KeyedStoreFastElementStub : public CodeStub { class KeyedLoadExternalArrayStub : public CodeStub { public: - explicit KeyedLoadExternalArrayStub(ExternalArrayType array_type) - : array_type_(array_type) { } + explicit KeyedLoadExternalArrayStub(JSObject::ElementsKind elements_kind) + : elements_kind_(elements_kind) { } Major MajorKey() { return KeyedLoadExternalArray; } - int MinorKey() { return array_type_; } + int MinorKey() { return elements_kind_; } void Generate(MacroAssembler* masm); @@ -988,17 +988,17 @@ class KeyedLoadExternalArrayStub : public CodeStub { DECLARE_ARRAY_STUB_PRINT(KeyedLoadExternalArrayStub) protected: - ExternalArrayType array_type_; + JSObject::ElementsKind elements_kind_; }; class KeyedStoreExternalArrayStub : public CodeStub { public: - explicit KeyedStoreExternalArrayStub(ExternalArrayType array_type) - : array_type_(array_type) { } + explicit KeyedStoreExternalArrayStub(JSObject::ElementsKind elements_kind) + : elements_kind_(elements_kind) { } Major MajorKey() { return KeyedStoreExternalArray; } - int MinorKey() { return array_type_; } + int MinorKey() { return elements_kind_; } void Generate(MacroAssembler* masm); @@ -1007,7 +1007,7 @@ class KeyedStoreExternalArrayStub : public CodeStub { DECLARE_ARRAY_STUB_PRINT(KeyedStoreExternalArrayStub) protected: - ExternalArrayType array_type_; + JSObject::ElementsKind elements_kind_; }; diff --git a/src/heap.h b/src/heap.h index 47b6ab7d8..8b0c83367 100644 --- a/src/heap.h +++ b/src/heap.h @@ -182,14 +182,14 @@ inline Heap* _inline_get_heap_(); V(value_of_symbol, "valueOf") \ V(InitializeVarGlobal_symbol, "InitializeVarGlobal") \ V(InitializeConstGlobal_symbol, "InitializeConstGlobal") \ - V(KeyedLoadSpecializedMonomorphic_symbol, \ - "KeyedLoadSpecializedMonomorphic") \ - V(KeyedLoadSpecializedPolymorphic_symbol, \ - "KeyedLoadSpecializedPolymorphic") \ - V(KeyedStoreSpecializedMonomorphic_symbol, \ - "KeyedStoreSpecializedMonomorphic") \ - V(KeyedStoreSpecializedPolymorphic_symbol, \ - "KeyedStoreSpecializedPolymorphic") \ + V(KeyedLoadElementMonomorphic_symbol, \ + "KeyedLoadElementMonomorphic") \ + V(KeyedLoadElementPolymorphic_symbol, \ + "KeyedLoadElementPolymorphic") \ + V(KeyedStoreElementMonomorphic_symbol, \ + "KeyedStoreElementMonomorphic") \ + V(KeyedStoreElementPolymorphic_symbol, \ + "KeyedStoreElementPolymorphic") \ V(stack_overflow_symbol, "kStackOverflowBoilerplate") \ V(illegal_access_symbol, "illegal access") \ V(out_of_memory_symbol, "out-of-memory") \ diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index fab6c917e..447416e29 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1355,34 +1355,39 @@ void HLoadKeyedSpecializedArrayElement::PrintDataTo( StringStream* stream) { external_pointer()->PrintNameTo(stream); stream->Add("."); - switch (array_type()) { - case kExternalByteArray: + switch (elements_kind()) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: stream->Add("byte"); break; - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: stream->Add("u_byte"); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: stream->Add("short"); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: stream->Add("u_short"); break; - case kExternalIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: stream->Add("int"); break; - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: stream->Add("u_int"); break; - case kExternalFloatArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: stream->Add("float"); break; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: stream->Add("double"); break; - case kExternalPixelArray: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: stream->Add("pixel"); break; + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: + UNREACHABLE(); + break; } stream->Add("["); key()->PrintNameTo(stream); @@ -1435,34 +1440,39 @@ void HStoreKeyedSpecializedArrayElement::PrintDataTo( StringStream* stream) { external_pointer()->PrintNameTo(stream); stream->Add("."); - switch (array_type()) { - case kExternalByteArray: + switch (elements_kind()) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: stream->Add("byte"); break; - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: stream->Add("u_byte"); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: stream->Add("short"); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: stream->Add("u_short"); break; - case kExternalIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: stream->Add("int"); break; - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: stream->Add("u_int"); break; - case kExternalFloatArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: stream->Add("float"); break; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: stream->Add("double"); break; - case kExternalPixelArray: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: stream->Add("pixel"); break; + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: + UNREACHABLE(); + break; } stream->Add("["); key()->PrintNameTo(stream); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 053752a9b..38db649c7 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -3474,11 +3474,11 @@ class HLoadKeyedSpecializedArrayElement: public HBinaryOperation { public: HLoadKeyedSpecializedArrayElement(HValue* external_elements, HValue* key, - ExternalArrayType array_type) + JSObject::ElementsKind elements_kind) : HBinaryOperation(external_elements, key), - array_type_(array_type) { - if (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray) { + elements_kind_(elements_kind) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || + elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { set_representation(Representation::Double()); } else { set_representation(Representation::Integer32()); @@ -3500,7 +3500,7 @@ class HLoadKeyedSpecializedArrayElement: public HBinaryOperation { HValue* external_pointer() { return OperandAt(0); } HValue* key() { return OperandAt(1); } - ExternalArrayType array_type() const { return array_type_; } + JSObject::ElementsKind elements_kind() const { return elements_kind_; } DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement) @@ -3509,11 +3509,11 @@ class HLoadKeyedSpecializedArrayElement: public HBinaryOperation { if (!other->IsLoadKeyedSpecializedArrayElement()) return false; HLoadKeyedSpecializedArrayElement* cast_other = HLoadKeyedSpecializedArrayElement::cast(other); - return array_type_ == cast_other->array_type(); + return elements_kind_ == cast_other->elements_kind(); } private: - ExternalArrayType array_type_; + JSObject::ElementsKind elements_kind_; }; @@ -3656,8 +3656,8 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { HStoreKeyedSpecializedArrayElement(HValue* external_elements, HValue* key, HValue* val, - ExternalArrayType array_type) - : array_type_(array_type) { + JSObject::ElementsKind elements_kind) + : elements_kind_(elements_kind) { SetFlag(kChangesSpecializedArrayElements); SetOperandAt(0, external_elements); SetOperandAt(1, key); @@ -3670,8 +3670,10 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { if (index == 0) { return Representation::External(); } else { - if (index == 2 && (array_type() == kExternalFloatArray || - array_type() == kExternalDoubleArray)) { + bool float_or_double_elements = + elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS || + elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS; + if (index == 2 && float_or_double_elements) { return Representation::Double(); } else { return Representation::Integer32(); @@ -3682,12 +3684,12 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { HValue* external_pointer() { return OperandAt(0); } HValue* key() { return OperandAt(1); } HValue* value() { return OperandAt(2); } - ExternalArrayType array_type() const { return array_type_; } + JSObject::ElementsKind elements_kind() const { return elements_kind_; } DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement) private: - ExternalArrayType array_type_; + JSObject::ElementsKind elements_kind_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index b53c4df2b..dcf5a159a 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -3809,7 +3809,7 @@ HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement( AddInstruction(external_elements); HLoadKeyedSpecializedArrayElement* pixel_array_value = new(zone()) HLoadKeyedSpecializedArrayElement( - external_elements, checked_key, expr->external_array_type()); + external_elements, checked_key, map->elements_kind()); return pixel_array_value; } @@ -3890,34 +3890,38 @@ HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( HLoadExternalArrayPointer* external_elements = new(zone()) HLoadExternalArrayPointer(elements); AddInstruction(external_elements); - ExternalArrayType array_type = expr->external_array_type(); - switch (array_type) { - case kExternalPixelArray: { + JSObject::ElementsKind elements_kind = map->elements_kind(); + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: { HClampToUint8* clamp = new(zone()) HClampToUint8(val); AddInstruction(clamp); val = clamp; break; } - case kExternalByteArray: - case kExternalUnsignedByteArray: - case kExternalShortArray: - case kExternalUnsignedShortArray: - case kExternalIntArray: - case kExternalUnsignedIntArray: { + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { HToInt32* floor_val = new(zone()) HToInt32(val); AddInstruction(floor_val); val = floor_val; break; } - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: + UNREACHABLE(); break; } return new(zone()) HStoreKeyedSpecializedArrayElement( external_elements, checked_key, val, - expr->external_array_type()); + map->elements_kind()); } diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 91baa229c..851e13048 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -2440,11 +2440,12 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { } -Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer, - LOperand* key, - ExternalArrayType array_type) { +Operand LCodeGen::BuildExternalArrayOperand( + LOperand* external_pointer, + LOperand* key, + JSObject::ElementsKind elements_kind) { Register external_pointer_reg = ToRegister(external_pointer); - int shift_size = ExternalArrayTypeToShiftSize(array_type); + int shift_size = ElementsKindToShiftSize(elements_kind); if (key->IsConstantOperand()) { int constant_value = ToInteger32(LConstantOperand::cast(key)); if (constant_value & 0xF0000000) { @@ -2460,35 +2461,35 @@ Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer, void LCodeGen::DoLoadKeyedSpecializedArrayElement( LLoadKeyedSpecializedArrayElement* instr) { - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildExternalArrayOperand(instr->external_pointer(), - instr->key(), array_type)); - if (array_type == kExternalFloatArray) { + instr->key(), elements_kind)); + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { XMMRegister result(ToDoubleRegister(instr->result())); __ movss(result, operand); __ cvtss2sd(result, result); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ movdbl(ToDoubleRegister(instr->result()), operand); } else { Register result(ToRegister(instr->result())); - switch (array_type) { - case kExternalByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: __ movsx_b(result, operand); break; - case kExternalUnsignedByteArray: - case kExternalPixelArray: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movzx_b(result, operand); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: __ movsx_w(result, operand); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzx_w(result, operand); break; - case kExternalIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: __ mov(result, operand); break; - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ mov(result, operand); __ test(result, Operand(result)); // TODO(danno): we could be more clever here, perhaps having a special @@ -2496,8 +2497,11 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( // happens, and generate code that returns a double rather than int. DeoptimizeIf(negative, instr->environment()); break; - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } @@ -3205,32 +3209,35 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { void LCodeGen::DoStoreKeyedSpecializedArrayElement( LStoreKeyedSpecializedArrayElement* instr) { - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildExternalArrayOperand(instr->external_pointer(), - instr->key(), array_type)); - if (array_type == kExternalFloatArray) { + instr->key(), elements_kind)); + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); __ movss(operand, xmm0); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ movdbl(operand, ToDoubleRegister(instr->value())); } else { Register value = ToRegister(instr->value()); - switch (array_type) { - case kExternalPixelArray: - case kExternalByteArray: - case kExternalUnsignedByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case JSObject::EXTERNAL_BYTE_ELEMENTS: __ mov_b(operand, value); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ mov_w(operand, value); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ mov(operand, value); break; - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 1a98d8dd6..9c4ebb76e 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -232,7 +232,7 @@ class LCodeGen BASE_EMBEDDED { int ToInteger32(LConstantOperand* op) const; Operand BuildExternalArrayOperand(LOperand* external_pointer, LOperand* key, - ExternalArrayType array_type); + JSObject::ElementsKind elements_kind); // Specific math operations - used from DoUnaryMathOperation. void EmitIntegerMathAbs(LUnaryMathOperation* instr); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 44af66119..0dbb77b29 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -1965,13 +1965,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( HLoadKeyedSpecializedArrayElement* instr) { - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); Representation representation(instr->representation()); ASSERT( - (representation.IsInteger32() && (array_type != kExternalFloatArray && - array_type != kExternalDoubleArray)) || - (representation.IsDouble() && (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray))); + (representation.IsInteger32() && + (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (representation.IsDouble() && + ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); @@ -1981,7 +1983,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* load_instr = DefineAsRegister(result); // An unsigned int array load might overflow and cause a deopt, make sure it // has an environment. - return (array_type == kExternalUnsignedIntArray) + return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ? AssignEnvironment(load_instr) : load_instr; } @@ -2019,21 +2021,23 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( HStoreKeyedSpecializedArrayElement* instr) { Representation representation(instr->value()->representation()); - ExternalArrayType array_type = instr->array_type(); - ASSERT( - (representation.IsInteger32() && (array_type != kExternalFloatArray && - array_type != kExternalDoubleArray)) || - (representation.IsDouble() && (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray))); + JSObject::ElementsKind elements_kind = instr->elements_kind(); + ASSERT( + (representation.IsInteger32() && + (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (representation.IsDouble() && + ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); LOperand* val = NULL; - if (array_type == kExternalByteArray || - array_type == kExternalUnsignedByteArray || - array_type == kExternalPixelArray) { + if (elements_kind == JSObject::EXTERNAL_BYTE_ELEMENTS || + elements_kind == JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS || + elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { // We need a byte register in this case for the value. val = UseFixed(instr->value(), eax); } else { diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 42cf521b9..0729295cb 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -1318,8 +1318,8 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } - ExternalArrayType array_type() const { - return hydrogen()->array_type(); + JSObject::ElementsKind elements_kind() const { + return hydrogen()->elements_kind(); } }; @@ -1807,8 +1807,8 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - ExternalArrayType array_type() const { - return hydrogen()->array_type(); + JSObject::ElementsKind elements_kind() const { + return hydrogen()->elements_kind(); } }; diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 325738813..9cefe710a 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -2699,7 +2699,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, } -MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( +MaybeObject* KeyedStoreStubCompiler::CompileStoreElement( Map* receiver_map) { // ----------- S t a t e ------------- // -- eax : value @@ -2707,9 +2707,15 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( // -- edx : receiver // -- esp[0] : return address // ----------------------------------- - bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; - MaybeObject* maybe_stub = - KeyedStoreFastElementStub(is_js_array).TryGetCode(); + MaybeObject* maybe_stub; + if (receiver_map->has_fast_elements()) { + bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; + maybe_stub = KeyedStoreFastElementStub(is_js_array).TryGetCode(); + } else { + ASSERT(receiver_map->has_external_array_elements()); + JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + maybe_stub = KeyedStoreExternalArrayStub(elements_kind).TryGetCode(); + } Code* stub; if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(edx, @@ -3163,13 +3169,20 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { } -MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { +MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { // ----------- S t a t e ------------- // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- - MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode(); + MaybeObject* maybe_stub; + if (receiver_map->has_fast_elements()) { + maybe_stub = KeyedLoadFastElementStub().TryGetCode(); + } else { + ASSERT(receiver_map->has_external_array_elements()); + JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + maybe_stub = KeyedLoadExternalArrayStub(elements_kind).TryGetCode(); + } Code* stub; if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(edx, @@ -3351,61 +3364,13 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { } -MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad( - JSObject*receiver, ExternalArrayType array_type) { - // ----------- S t a t e ------------- - // -- eax : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - MaybeObject* maybe_stub = - KeyedLoadExternalArrayStub(array_type).TryGetCode(); - Code* stub; - if (!maybe_stub->To(&stub)) return maybe_stub; - __ DispatchMap(edx, - Handle(receiver->map()), - Handle(stub), - DO_SMI_CHECK); - - Handle ic = isolate()->builtins()->KeyedLoadIC_Miss(); - __ jmp(ic, RelocInfo::CODE_TARGET); - - // Return the generated code. - return GetCode(); -} - - -MaybeObject* ExternalArrayStoreStubCompiler::CompileStore( - JSObject* receiver, ExternalArrayType array_type) { - // ----------- S t a t e ------------- - // -- eax : value - // -- ecx : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - MaybeObject* maybe_stub = - KeyedStoreExternalArrayStub(array_type).TryGetCode(); - Code* stub; - if (!maybe_stub->To(&stub)) return maybe_stub; - __ DispatchMap(edx, - Handle(receiver->map()), - Handle(stub), - DO_SMI_CHECK); - - Handle ic = isolate()->builtins()->KeyedStoreIC_Miss(); - __ jmp(ic, RelocInfo::CODE_TARGET); - - return GetCode(); -} - - #undef __ #define __ ACCESS_MASM(masm) void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, - ExternalArrayType array_type) { + JSObject::ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- eax : key // -- edx : receiver @@ -3429,28 +3394,28 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ j(above_equal, &miss_force_generic); __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); // ebx: base pointer of external storage - switch (array_type) { - case kExternalByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: __ movsx_b(eax, Operand(ebx, ecx, times_1, 0)); break; - case kExternalUnsignedByteArray: - case kExternalPixelArray: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: __ movzx_b(eax, Operand(ebx, ecx, times_1, 0)); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: __ movsx_w(eax, Operand(ebx, ecx, times_2, 0)); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzx_w(eax, Operand(ebx, ecx, times_2, 0)); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case JSObject::EXTERNAL_INT_ELEMENTS: __ mov(ecx, Operand(ebx, ecx, times_4, 0)); break; - case kExternalFloatArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: __ fld_s(Operand(ebx, ecx, times_4, 0)); break; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: __ fld_d(Operand(ebx, ecx, times_8, 0)); break; default: @@ -3463,17 +3428,17 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // For floating-point array type: // FP(0): value - if (array_type == kExternalIntArray || - array_type == kExternalUnsignedIntArray) { + if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS || + elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { // For the Int and UnsignedInt array types, we need to see whether // the value can be represented in a Smi. If not, we need to convert // it to a HeapNumber. Label box_int; - if (array_type == kExternalIntArray) { + if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { __ cmp(ecx, 0xC0000000); __ j(sign, &box_int); } else { - ASSERT_EQ(array_type, kExternalUnsignedIntArray); + ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); // The test is different for unsigned int values. Since we need // the value to be in the range of a positive smi, we can't // handle either of the top two bits being set in the value. @@ -3489,12 +3454,12 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // Allocate a HeapNumber for the int and perform int-to-double // conversion. - if (array_type == kExternalIntArray) { + if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { __ push(ecx); __ fild_s(Operand(esp, 0)); __ pop(ecx); } else { - ASSERT(array_type == kExternalUnsignedIntArray); + ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); // Need to zero-extend the value. // There's no fild variant for unsigned values, so zero-extend // to a 64-bit int manually. @@ -3510,8 +3475,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(eax, ecx); __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ ret(0); - } else if (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || + elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); @@ -3561,7 +3526,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, - ExternalArrayType array_type) { + JSObject::ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- eax : key // -- edx : receiver @@ -3592,7 +3557,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // edi: elements array // ebx: untagged index __ test(eax, Immediate(kSmiTagMask)); - if (array_type == kExternalPixelArray) + if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) __ j(not_equal, &slow); else __ j(not_equal, &check_heap_number); @@ -3602,8 +3567,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ SmiUntag(ecx); __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); // ecx: base pointer of external storage - switch (array_type) { - case kExternalPixelArray: + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: { // Clamp the value to [0..255]. Label done; __ test(ecx, Immediate(0xFFFFFF00)); @@ -3614,27 +3579,27 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( } __ mov_b(Operand(edi, ebx, times_1, 0), ecx); break; - case kExternalByteArray: - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ mov_b(Operand(edi, ebx, times_1, 0), ecx); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ mov_w(Operand(edi, ebx, times_2, 0), ecx); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ mov(Operand(edi, ebx, times_4, 0), ecx); break; - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: // Need to perform int-to-float conversion. __ push(ecx); __ fild_s(Operand(esp, 0)); __ pop(ecx); - if (array_type == kExternalFloatArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { __ fstp_s(Operand(edi, ebx, times_4, 0)); - } else { // array_type == kExternalDoubleArray. + } else { // elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS. __ fstp_d(Operand(edi, ebx, times_8, 0)); } break; @@ -3645,7 +3610,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ ret(0); // Return the original value. // TODO(danno): handle heap number -> pixel array conversion - if (array_type != kExternalPixelArray) { + if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { __ bind(&check_heap_number); // eax: value // edx: receiver @@ -3662,11 +3627,11 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); // ebx: untagged index // edi: base pointer of external storage - if (array_type == kExternalFloatArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ fstp_s(Operand(edi, ebx, times_4, 0)); __ ret(0); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ fstp_d(Operand(edi, ebx, times_8, 0)); __ ret(0); @@ -3679,14 +3644,14 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // (code-stubs-ia32.cc) is roughly what is needed here though the // conversion failure case does not need to be handled. if (CpuFeatures::IsSupported(SSE2)) { - if (array_type != kExternalIntArray && - array_type != kExternalUnsignedIntArray) { + if (elements_kind != JSObject::EXTERNAL_INT_ELEMENTS && + elements_kind != JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { ASSERT(CpuFeatures::IsSupported(SSE2)); CpuFeatures::Scope scope(SSE2); __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); // ecx: untagged integer value - switch (array_type) { - case kExternalPixelArray: + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: { // Clamp the value to [0..255]. Label done; __ test(ecx, Immediate(0xFFFFFF00)); @@ -3697,12 +3662,12 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( } __ mov_b(Operand(edi, ebx, times_1, 0), ecx); break; - case kExternalByteArray: - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ mov_b(Operand(edi, ebx, times_1, 0), ecx); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ mov_w(Operand(edi, ebx, times_2, 0), ecx); break; default: @@ -3775,8 +3740,6 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( } - - void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- eax : key diff --git a/src/ic.cc b/src/ic.cc index 030ca716c..eca831587 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1070,10 +1070,10 @@ void LoadIC::UpdateCaches(LookupResult* lookup, String* KeyedLoadIC::GetStubNameForCache(IC::State ic_state) { if (ic_state == MONOMORPHIC) { - return isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol(); + return isolate()->heap()->KeyedLoadElementMonomorphic_symbol(); } else { ASSERT(ic_state == MEGAMORPHIC); - return isolate()->heap()->KeyedLoadSpecializedPolymorphic_symbol(); + return isolate()->heap()->KeyedLoadElementPolymorphic_symbol(); } } @@ -1085,8 +1085,8 @@ MaybeObject* KeyedLoadIC::GetFastElementStubWithoutMapCheck( MaybeObject* KeyedLoadIC::GetExternalArrayStubWithoutMapCheck( - ExternalArrayType array_type) { - return KeyedLoadExternalArrayStub(array_type).TryGetCode(); + JSObject::ElementsKind elements_kind) { + return KeyedLoadExternalArrayStub(elements_kind).TryGetCode(); } @@ -1697,8 +1697,8 @@ MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck( return generic_stub; } Code* default_stub = Code::cast(maybe_default_stub); - return GetExternalArrayStubWithoutMapCheck( - default_stub->external_array_type()); + Map* first_map = default_stub->FindFirstMap(); + return GetExternalArrayStubWithoutMapCheck(first_map->elements_kind()); } else if (receiver_map->has_fast_elements()) { bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; return GetFastElementStubWithoutMapCheck(is_js_array); @@ -1713,14 +1713,10 @@ MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver, StrictModeFlag strict_mode, Code* generic_stub) { Code* result = NULL; - if (receiver->HasExternalArrayElements()) { + if (receiver->HasFastElements() || + receiver->HasExternalArrayElements()) { MaybeObject* maybe_stub = - isolate()->stub_cache()->ComputeKeyedLoadOrStoreExternalArray( - receiver, is_store, strict_mode); - if (!maybe_stub->To(&result)) return maybe_stub; - } else if (receiver->map()->has_fast_elements()) { - MaybeObject* maybe_stub = - isolate()->stub_cache()->ComputeKeyedLoadOrStoreFastElement( + isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement( receiver, is_store, strict_mode); if (!maybe_stub->To(&result)) return maybe_stub; } else { @@ -1732,10 +1728,10 @@ MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver, String* KeyedStoreIC::GetStubNameForCache(IC::State ic_state) { if (ic_state == MONOMORPHIC) { - return isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol(); + return isolate()->heap()->KeyedStoreElementMonomorphic_symbol(); } else { ASSERT(ic_state == MEGAMORPHIC); - return isolate()->heap()->KeyedStoreSpecializedPolymorphic_symbol(); + return isolate()->heap()->KeyedStoreElementPolymorphic_symbol(); } } @@ -1747,8 +1743,8 @@ MaybeObject* KeyedStoreIC::GetFastElementStubWithoutMapCheck( MaybeObject* KeyedStoreIC::GetExternalArrayStubWithoutMapCheck( - ExternalArrayType array_type) { - return KeyedStoreExternalArrayStub(array_type).TryGetCode(); + JSObject::ElementsKind elements_kind) { + return KeyedStoreExternalArrayStub(elements_kind).TryGetCode(); } diff --git a/src/ic.h b/src/ic.h index 4cf3193eb..7af09ee3a 100644 --- a/src/ic.h +++ b/src/ic.h @@ -350,7 +350,7 @@ class KeyedIC: public IC { bool is_js_array) = 0; virtual MaybeObject* GetExternalArrayStubWithoutMapCheck( - ExternalArrayType array_type) = 0; + JSObject::ElementsKind elements_kind) = 0; protected: virtual Code* string_stub() { @@ -422,7 +422,7 @@ class KeyedLoadIC: public KeyedIC { bool is_js_array); virtual MaybeObject* GetExternalArrayStubWithoutMapCheck( - ExternalArrayType array_type); + JSObject::ElementsKind elements_kind); protected: virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } @@ -572,7 +572,7 @@ class KeyedStoreIC: public KeyedIC { bool is_js_array); virtual MaybeObject* GetExternalArrayStubWithoutMapCheck( - ExternalArrayType array_type); + JSObject::ElementsKind elements_kind); protected: virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } diff --git a/src/lithium.cc b/src/lithium.cc index 62b263be1..3309a0f28 100644 --- a/src/lithium.cc +++ b/src/lithium.cc @@ -166,21 +166,25 @@ void LPointerMap::PrintTo(StringStream* stream) { } -int ExternalArrayTypeToShiftSize(ExternalArrayType type) { - switch (type) { - case kExternalByteArray: - case kExternalUnsignedByteArray: - case kExternalPixelArray: +int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind) { + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: return 0; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: return 1; - case kExternalIntArray: - case kExternalUnsignedIntArray: - case kExternalFloatArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: return 2; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: return 3; + case JSObject::FAST_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: + return kPointerSizeLog2; } UNREACHABLE(); return 0; diff --git a/src/lithium.h b/src/lithium.h index ea023a980..3f8a6ba4d 100644 --- a/src/lithium.h +++ b/src/lithium.h @@ -585,7 +585,7 @@ class DeepIterator BASE_EMBEDDED { }; -int ExternalArrayTypeToShiftSize(ExternalArrayType type); +int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind); } } // namespace v8::internal diff --git a/src/objects-inl.h b/src/objects-inl.h index 90dfde61c..204c4cb82 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -2841,19 +2841,6 @@ void Code::set_check_type(CheckType value) { } -ExternalArrayType Code::external_array_type() { - ASSERT(is_keyed_load_stub() || is_keyed_store_stub()); - byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset); - return static_cast(type); -} - - -void Code::set_external_array_type(ExternalArrayType value) { - ASSERT(is_keyed_load_stub() || is_keyed_store_stub()); - WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value); -} - - byte Code::unary_op_type() { ASSERT(is_unary_op_stub()); return READ_BYTE_FIELD(this, kUnaryOpTypeOffset); diff --git a/src/objects.h b/src/objects.h index 5330a9587..f9f66bf0c 100644 --- a/src/objects.h +++ b/src/objects.h @@ -3575,12 +3575,6 @@ class Code: public HeapObject { inline CheckType check_type(); inline void set_check_type(CheckType value); - // [external array type]: For kind KEYED_EXTERNAL_ARRAY_LOAD_IC and - // KEYED_EXTERNAL_ARRAY_STORE_IC, identifies the type of external - // array that the code stub is specialized for. - inline ExternalArrayType external_array_type(); - inline void set_external_array_type(ExternalArrayType value); - // [type-recording unary op type]: For all UNARY_OP_IC. inline byte unary_op_type(); inline void set_unary_op_type(byte value); diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 8c6d84c61..7bbb333f1 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -485,38 +485,7 @@ MaybeObject* StubCache::ComputeStoreField(String* name, } -namespace { - -ExternalArrayType ElementsKindToExternalArrayType(JSObject::ElementsKind kind) { - switch (kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - return kExternalByteArray; - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - return kExternalUnsignedByteArray; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - return kExternalShortArray; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - return kExternalUnsignedShortArray; - case JSObject::EXTERNAL_INT_ELEMENTS: - return kExternalIntArray; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - return kExternalUnsignedIntArray; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - return kExternalFloatArray; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - return kExternalDoubleArray; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - return kExternalPixelArray; - default: - UNREACHABLE(); - return static_cast(0); - } -} - -} // anonymous namespace - - -MaybeObject* StubCache::ComputeKeyedLoadOrStoreExternalArray( +MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement( JSObject* receiver, bool is_store, StrictModeFlag strict_mode) { @@ -526,67 +495,19 @@ MaybeObject* StubCache::ComputeKeyedLoadOrStoreExternalArray( Code::KEYED_LOAD_IC, NORMAL, strict_mode); - ExternalArrayType array_type = - ElementsKindToExternalArrayType(receiver->GetElementsKind()); String* name = is_store - ? isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol() - : isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol(); - Object* maybe_code = receiver->map()->FindInCodeCache(name, flags); - if (!maybe_code->IsUndefined()) return Code::cast(maybe_code); - - MaybeObject* maybe_new_code = NULL; - if (is_store) { - ExternalArrayStoreStubCompiler compiler(strict_mode); - maybe_new_code = compiler.CompileStore(receiver, array_type); - } else { - ExternalArrayLoadStubCompiler compiler(strict_mode); - maybe_new_code = compiler.CompileLoad(receiver, array_type); - } - Code* code; - if (!maybe_new_code->To(&code)) return maybe_new_code; - code->set_external_array_type(array_type); - if (is_store) { - PROFILE(isolate_, - CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_STORE_IC_TAG, - Code::cast(code), 0)); - } else { - PROFILE(isolate_, - CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG, - Code::cast(code), 0)); - } - ASSERT(code->IsCode()); - Object* result; - { MaybeObject* maybe_result = - receiver->UpdateMapCodeCache(name, Code::cast(code)); - if (!maybe_result->ToObject(&result)) return maybe_result; - } - return code; -} - - -MaybeObject* StubCache::ComputeKeyedLoadOrStoreFastElement( - JSObject* receiver, - bool is_store, - StrictModeFlag strict_mode) { - Code::Flags flags = - Code::ComputeMonomorphicFlags( - is_store ? Code::KEYED_STORE_IC : - Code::KEYED_LOAD_IC, - NORMAL, - strict_mode); - String* name = is_store - ? isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol() - : isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol(); + ? isolate()->heap()->KeyedStoreElementMonomorphic_symbol() + : isolate()->heap()->KeyedLoadElementMonomorphic_symbol(); Object* maybe_code = receiver->map()->FindInCodeCache(name, flags); if (!maybe_code->IsUndefined()) return Code::cast(maybe_code); MaybeObject* maybe_new_code = NULL; if (is_store) { KeyedStoreStubCompiler compiler(strict_mode); - maybe_new_code = compiler.CompileStoreFastElement(receiver->map()); + maybe_new_code = compiler.CompileStoreElement(receiver->map()); } else { KeyedLoadStubCompiler compiler; - maybe_new_code = compiler.CompileLoadFastElement(receiver->map()); + maybe_new_code = compiler.CompileLoadElement(receiver->map()); } Code* code; if (!maybe_new_code->To(&code)) return maybe_new_code; @@ -1923,38 +1844,4 @@ void CallOptimization::AnalyzePossibleApiFunction(JSFunction* function) { } -MaybeObject* ExternalArrayLoadStubCompiler::GetCode() { - Object* result; - Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, - NORMAL, - strict_mode_); - { MaybeObject* maybe_result = GetCodeWithFlags(flags, - "ExternalArrayLoadStub"); - if (!maybe_result->ToObject(&result)) return maybe_result; - } - Code* code = Code::cast(result); - USE(code); - PROFILE(isolate(), - CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayLoadStub")); - return result; -} - - -MaybeObject* ExternalArrayStoreStubCompiler::GetCode() { - Object* result; - Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, - NORMAL, - strict_mode_); - { MaybeObject* maybe_result = GetCodeWithFlags(flags, - "ExternalArrayStoreStub"); - if (!maybe_result->ToObject(&result)) return maybe_result; - } - Code* code = Code::cast(result); - USE(code); - PROFILE(isolate(), - CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStoreStub")); - return result; -} - - } } // namespace v8::internal diff --git a/src/stub-cache.h b/src/stub-cache.h index a1243c22a..8ecf8bbcf 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -183,15 +183,11 @@ class StubCache { Map* transition, StrictModeFlag strict_mode); - MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreExternalArray( + MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreElement( JSObject* receiver, bool is_store, StrictModeFlag strict_mode); - MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreFastElement( - JSObject* receiver, - bool is_store, - StrictModeFlag strict_mode); // --- MUST_USE_RESULT MaybeObject* ComputeCallField( @@ -650,14 +646,14 @@ class KeyedLoadStubCompiler: public StubCompiler { MUST_USE_RESULT MaybeObject* CompileLoadStringLength(String* name); MUST_USE_RESULT MaybeObject* CompileLoadFunctionPrototype(String* name); - MUST_USE_RESULT MaybeObject* CompileLoadFastElement(Map* receiver_map); + MUST_USE_RESULT MaybeObject* CompileLoadElement(Map* receiver_map); MUST_USE_RESULT MaybeObject* CompileLoadMegamorphic( MapList* receiver_maps, CodeList* handler_ics); static void GenerateLoadExternalArray(MacroAssembler* masm, - ExternalArrayType array_type); + JSObject::ElementsKind elements_kind); static void GenerateLoadFastElement(MacroAssembler* masm); @@ -705,7 +701,7 @@ class KeyedStoreStubCompiler: public StubCompiler { Map* transition, String* name); - MUST_USE_RESULT MaybeObject* CompileStoreFastElement(Map* receiver_map); + MUST_USE_RESULT MaybeObject* CompileStoreElement(Map* receiver_map); MUST_USE_RESULT MaybeObject* CompileStoreMegamorphic( MapList* receiver_maps, @@ -715,7 +711,7 @@ class KeyedStoreStubCompiler: public StubCompiler { bool is_js_array); static void GenerateStoreExternalArray(MacroAssembler* masm, - ExternalArrayType array_type); + JSObject::ElementsKind elements_kind); private: MaybeObject* GetCode(PropertyType type, @@ -894,35 +890,6 @@ class CallOptimization BASE_EMBEDDED { CallHandlerInfo* api_call_info_; }; -class ExternalArrayLoadStubCompiler: public StubCompiler { - public: - explicit ExternalArrayLoadStubCompiler(StrictModeFlag strict_mode) - : strict_mode_(strict_mode) { } - - MUST_USE_RESULT MaybeObject* CompileLoad( - JSObject* receiver, ExternalArrayType array_type); - - private: - MaybeObject* GetCode(); - - StrictModeFlag strict_mode_; -}; - - -class ExternalArrayStoreStubCompiler: public StubCompiler { - public: - explicit ExternalArrayStoreStubCompiler(StrictModeFlag strict_mode) - : strict_mode_(strict_mode) {} - - MUST_USE_RESULT MaybeObject* CompileStore( - JSObject* receiver, ExternalArrayType array_type); - - private: - MaybeObject* GetCode(); - - StrictModeFlag strict_mode_; -}; - } } // namespace v8::internal diff --git a/src/type-info.cc b/src/type-info.cc index f5d2afbe5..819fbba26 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -171,20 +171,6 @@ CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { return check; } -ExternalArrayType TypeFeedbackOracle::GetKeyedLoadExternalArrayType( - Property* expr) { - Handle stub = GetInfo(expr->id()); - ASSERT(stub->IsCode()); - return Code::cast(*stub)->external_array_type(); -} - -ExternalArrayType TypeFeedbackOracle::GetKeyedStoreExternalArrayType( - Expression* expr) { - Handle stub = GetInfo(expr->id()); - ASSERT(stub->IsCode()); - return Code::cast(*stub)->external_array_type(); -} - Handle TypeFeedbackOracle::GetPrototypeForPrimitiveCheck( CheckType check) { JSFunction* function = NULL; diff --git a/src/type-info.h b/src/type-info.h index 828e3c72c..107e563fe 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -228,9 +228,6 @@ class TypeFeedbackOracle BASE_EMBEDDED { Handle name, CallKind call_kind); - ExternalArrayType GetKeyedLoadExternalArrayType(Property* expr); - ExternalArrayType GetKeyedStoreExternalArrayType(Expression* expr); - CheckType GetCallCheckType(Call* expr); Handle GetPrototypeForPrimitiveCheck(CheckType check); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 15542147e..fb0520ae6 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -2445,11 +2445,12 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { } -Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer, - LOperand* key, - ExternalArrayType array_type) { +Operand LCodeGen::BuildExternalArrayOperand( + LOperand* external_pointer, + LOperand* key, + JSObject::ElementsKind elements_kind) { Register external_pointer_reg = ToRegister(external_pointer); - int shift_size = ExternalArrayTypeToShiftSize(array_type); + int shift_size = ElementsKindToShiftSize(elements_kind); if (key->IsConstantOperand()) { int constant_value = ToInteger32(LConstantOperand::cast(key)); if (constant_value & 0xF0000000) { @@ -2465,35 +2466,35 @@ Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer, void LCodeGen::DoLoadKeyedSpecializedArrayElement( LLoadKeyedSpecializedArrayElement* instr) { - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildExternalArrayOperand(instr->external_pointer(), - instr->key(), array_type)); - if (array_type == kExternalFloatArray) { + instr->key(), elements_kind)); + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { XMMRegister result(ToDoubleRegister(instr->result())); __ movss(result, operand); __ cvtss2sd(result, result); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ movsd(ToDoubleRegister(instr->result()), operand); } else { Register result(ToRegister(instr->result())); - switch (array_type) { - case kExternalByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: __ movsxbq(result, operand); break; - case kExternalUnsignedByteArray: - case kExternalPixelArray: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: __ movzxbq(result, operand); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: __ movsxwq(result, operand); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzxwq(result, operand); break; - case kExternalIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: __ movsxlq(result, operand); break; - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(result, operand); __ testl(result, result); // TODO(danno): we could be more clever here, perhaps having a special @@ -2501,8 +2502,11 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( // happens, and generate code that returns a double rather than int. DeoptimizeIf(negative, instr->environment()); break; - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } @@ -3189,33 +3193,36 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { void LCodeGen::DoStoreKeyedSpecializedArrayElement( LStoreKeyedSpecializedArrayElement* instr) { - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildExternalArrayOperand(instr->external_pointer(), - instr->key(), array_type)); - if (array_type == kExternalFloatArray) { + instr->key(), elements_kind)); + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { XMMRegister value(ToDoubleRegister(instr->value())); __ cvtsd2ss(value, value); __ movss(operand, value); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ movsd(operand, ToDoubleRegister(instr->value())); } else { Register value(ToRegister(instr->value())); - switch (array_type) { - case kExternalPixelArray: - case kExternalByteArray: - case kExternalUnsignedByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movb(operand, value); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movw(operand, value); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(operand, value); break; - case kExternalFloatArray: - case kExternalDoubleArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index 7c9f2a03a..25e9c40c9 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -215,9 +215,10 @@ class LCodeGen BASE_EMBEDDED { Register ToRegister(int index) const; XMMRegister ToDoubleRegister(int index) const; - Operand BuildExternalArrayOperand(LOperand* external_pointer, - LOperand* key, - ExternalArrayType array_type); + Operand BuildExternalArrayOperand( + LOperand* external_pointer, + LOperand* key, + JSObject::ElementsKind elements_kind); // Specific math operations - used from DoUnaryMathOperation. void EmitIntegerMathAbs(LUnaryMathOperation* instr); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 853f65657..a68f57d6e 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1920,13 +1920,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( HLoadKeyedSpecializedArrayElement* instr) { - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); Representation representation(instr->representation()); ASSERT( - (representation.IsInteger32() && (array_type != kExternalFloatArray && - array_type != kExternalDoubleArray)) || - (representation.IsDouble() && (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray))); + (representation.IsInteger32() && + (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (representation.IsDouble() && + ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); @@ -1935,7 +1937,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* load_instr = DefineAsRegister(result); // An unsigned int array load might overflow and cause a deopt, make sure it // has an environment. - return (array_type == kExternalUnsignedIntArray) ? + return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ? AssignEnvironment(load_instr) : load_instr; } @@ -1971,18 +1973,21 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( HStoreKeyedSpecializedArrayElement* instr) { Representation representation(instr->value()->representation()); - ExternalArrayType array_type = instr->array_type(); + JSObject::ElementsKind elements_kind = instr->elements_kind(); ASSERT( - (representation.IsInteger32() && (array_type != kExternalFloatArray && - array_type != kExternalDoubleArray)) || - (representation.IsDouble() && (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray))); + (representation.IsInteger32() && + (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (representation.IsDouble() && + ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); - bool val_is_temp_register = array_type == kExternalPixelArray || - array_type == kExternalFloatArray; + bool val_is_temp_register = + elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS || + elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS; LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) : UseRegister(instr->value()); diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 081b2bf3e..825378cb1 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -1297,8 +1297,8 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } - ExternalArrayType array_type() const { - return hydrogen()->array_type(); + JSObject::ElementsKind elements_kind() const { + return hydrogen()->elements_kind(); } }; @@ -1751,8 +1751,8 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - ExternalArrayType array_type() const { - return hydrogen()->array_type(); + JSObject::ElementsKind elements_kind() const { + return hydrogen()->elements_kind(); } }; diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index ab38a7f35..45d610bc4 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -2530,7 +2530,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, } -MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( +MaybeObject* KeyedStoreStubCompiler::CompileStoreElement( Map* receiver_map) { // ----------- S t a t e ------------- // -- rax : value @@ -2538,9 +2538,15 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- - bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; - MaybeObject* maybe_stub = - KeyedStoreFastElementStub(is_js_array).TryGetCode(); + MaybeObject* maybe_stub; + if (receiver_map->has_fast_elements()) { + bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; + maybe_stub = KeyedStoreFastElementStub(is_js_array).TryGetCode(); + } else { + ASSERT(receiver_map->has_external_array_elements()); + JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + maybe_stub = KeyedStoreExternalArrayStub(elements_kind).TryGetCode(); + } Code* stub; if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(rdx, @@ -2990,13 +2996,20 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { } -MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { +MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { // ----------- S t a t e ------------- // -- rax : key // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- - MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode(); + MaybeObject* maybe_stub; + if (receiver_map->has_fast_elements()) { + maybe_stub = KeyedLoadFastElementStub().TryGetCode(); + } else { + ASSERT(receiver_map->has_external_array_elements()); + JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + maybe_stub = KeyedLoadExternalArrayStub(elements_kind).TryGetCode(); + } Code* stub; if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(rdx, @@ -3176,60 +3189,13 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { } -MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad( - JSObject*receiver, ExternalArrayType array_type) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- - MaybeObject* maybe_stub = - KeyedLoadExternalArrayStub(array_type).TryGetCode(); - Code* stub; - if (!maybe_stub->To(&stub)) return maybe_stub; - __ DispatchMap(rdx, - Handle(receiver->map()), - Handle(stub), - DO_SMI_CHECK); - - Handle ic = isolate()->builtins()->KeyedLoadIC_Miss(); - __ jmp(ic, RelocInfo::CODE_TARGET); - - // Return the generated code. - return GetCode(); -} - -MaybeObject* ExternalArrayStoreStubCompiler::CompileStore( - JSObject* receiver, ExternalArrayType array_type) { - // ----------- S t a t e ------------- - // -- rax : value - // -- rcx : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- - MaybeObject* maybe_stub = - KeyedStoreExternalArrayStub(array_type).TryGetCode(); - Code* stub; - if (!maybe_stub->To(&stub)) return maybe_stub; - __ DispatchMap(rdx, - Handle(receiver->map()), - Handle(stub), - DO_SMI_CHECK); - - Handle ic = isolate()->builtins()->KeyedStoreIC_Miss(); - __ jmp(ic, RelocInfo::CODE_TARGET); - - return GetCode(); -} - - #undef __ #define __ ACCESS_MASM(masm) void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, - ExternalArrayType array_type) { + JSObject::ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- rax : key // -- rdx : receiver @@ -3256,30 +3222,30 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // rbx: elements array __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); // rbx: base pointer of external storage - switch (array_type) { - case kExternalByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); break; - case kExternalPixelArray: - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0)); break; - case kExternalShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0)); break; - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); break; - case kExternalIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0)); break; - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(rcx, Operand(rbx, rcx, times_4, 0)); break; - case kExternalFloatArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0)); break; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: __ movsd(xmm0, Operand(rbx, rcx, times_8, 0)); break; default: @@ -3295,7 +3261,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // xmm0: value as double. ASSERT(kSmiValueSize == 32); - if (array_type == kExternalUnsignedIntArray) { + if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { // For the UnsignedInt array type, we need to see whether // the value can be represented in a Smi. If not, we need to convert // it to a HeapNumber. @@ -3319,8 +3285,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); __ movq(rax, rcx); __ ret(0); - } else if (array_type == kExternalFloatArray || - array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || + elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. __ AllocateHeapNumber(rcx, rbx, &slow); @@ -3363,7 +3329,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, - ExternalArrayType array_type) { + JSObject::ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- rax : value // -- rcx : key @@ -3393,7 +3359,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // rbx: elements array // rdi: untagged key Label check_heap_number; - if (array_type == kExternalPixelArray) { + if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { // Float to pixel conversion is only implemented in the runtime for now. __ JumpIfNotSmi(rax, &slow); } else { @@ -3403,8 +3369,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ SmiToInteger32(rdx, rax); __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); // rbx: base pointer of external storage - switch (array_type) { - case kExternalPixelArray: + switch (elements_kind) { + case JSObject::EXTERNAL_PIXEL_ELEMENTS: { // Clamp the value to [0..255]. Label done; __ testl(rdx, Immediate(0xFFFFFF00)); @@ -3415,36 +3381,38 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( } __ movb(Operand(rbx, rdi, times_1, 0), rdx); break; - case kExternalByteArray: - case kExternalUnsignedByteArray: + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movb(Operand(rbx, rdi, times_1, 0), rdx); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movw(Operand(rbx, rdi, times_2, 0), rdx); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(Operand(rbx, rdi, times_4, 0), rdx); break; - case kExternalFloatArray: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: // Need to perform int-to-float conversion. __ cvtlsi2ss(xmm0, rdx); __ movss(Operand(rbx, rdi, times_4, 0), xmm0); break; - case kExternalDoubleArray: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: // Need to perform int-to-float conversion. __ cvtlsi2sd(xmm0, rdx); __ movsd(Operand(rbx, rdi, times_8, 0), xmm0); break; - default: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; } __ ret(0); // TODO(danno): handle heap number -> pixel array conversion - if (array_type != kExternalPixelArray) { + if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { __ bind(&check_heap_number); // rax: value // rcx: key (a smi) @@ -3463,11 +3431,11 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // rdi: untagged index // rbx: base pointer of external storage // top of FPU stack: value - if (array_type == kExternalFloatArray) { + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { __ cvtsd2ss(xmm0, xmm0); __ movss(Operand(rbx, rdi, times_4, 0), xmm0); __ ret(0); - } else if (array_type == kExternalDoubleArray) { + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { __ movsd(Operand(rbx, rdi, times_8, 0), xmm0); __ ret(0); } else { @@ -3480,26 +3448,30 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // rdx: value (converted to an untagged integer) // rdi: untagged index // rbx: base pointer of external storage - switch (array_type) { - case kExternalByteArray: - case kExternalUnsignedByteArray: + switch (elements_kind) { + case JSObject::EXTERNAL_BYTE_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ cvttsd2si(rdx, xmm0); __ movb(Operand(rbx, rdi, times_1, 0), rdx); break; - case kExternalShortArray: - case kExternalUnsignedShortArray: + case JSObject::EXTERNAL_SHORT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ cvttsd2si(rdx, xmm0); __ movw(Operand(rbx, rdi, times_2, 0), rdx); break; - case kExternalIntArray: - case kExternalUnsignedIntArray: { + case JSObject::EXTERNAL_INT_ELEMENTS: + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: // Convert to int64, so that NaN and infinities become // 0x8000000000000000, which is zero mod 2^32. __ cvttsd2siq(rdx, xmm0); __ movl(Operand(rbx, rdi, times_4, 0), rdx); break; - } - default: + case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case JSObject::FAST_ELEMENTS: + case JSObject::FAST_DOUBLE_ELEMENTS: + case JSObject::DICTIONARY_ELEMENTS: UNREACHABLE(); break; }