| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index 85a60118b7673b0d00a90abe8af3167a3bc4e934..5d0783a18a652ec4bf3f18e531d7678f22e56333 100644
|
| --- a/src/code-stub-assembler.cc
|
| +++ b/src/code-stub-assembler.cc
|
| @@ -6,7 +6,6 @@
|
| #include "src/code-factory.h"
|
| #include "src/frames-inl.h"
|
| #include "src/frames.h"
|
| -#include "src/ic/handler-configuration.h"
|
| #include "src/ic/stub-cache.h"
|
|
|
| namespace v8 {
|
| @@ -3426,261 +3425,31 @@
|
| }
|
| }
|
|
|
| -// |is_jsarray| should be non-zero for JSArrays.
|
| -void CodeStubAssembler::EmitBoundsCheck(Node* object, Node* elements,
|
| - Node* intptr_key, Node* is_jsarray,
|
| - Label* miss) {
|
| - Variable var_length(this, MachineRepresentation::kTagged);
|
| - Label if_array(this), length_loaded(this, &var_length);
|
| - GotoUnless(WordEqual(is_jsarray, IntPtrConstant(0)), &if_array);
|
| - {
|
| - var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements)));
|
| - Goto(&length_loaded);
|
| - }
|
| - Bind(&if_array);
|
| - {
|
| - var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset)));
|
| - Goto(&length_loaded);
|
| - }
|
| - Bind(&length_loaded);
|
| - GotoUnless(UintPtrLessThan(intptr_key, var_length.value()), miss);
|
| -}
|
| -
|
| -// |key| should be untagged (int32).
|
| -void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements,
|
| - Node* elements_kind, Node* key,
|
| - Label* if_hole, Label* rebox_double,
|
| - Variable* var_double_value,
|
| - Label* miss) {
|
| - Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this),
|
| - if_fast_double(this), if_fast_holey_double(this),
|
| - unimplemented_elements_kind(this);
|
| - STATIC_ASSERT(LAST_ELEMENTS_KIND == LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
|
| - GotoIf(
|
| - IntPtrGreaterThanOrEqual(
|
| - elements_kind, IntPtrConstant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND)),
|
| - &if_typed_array);
|
| -
|
| - int32_t kinds[] = {// Handled by if_fast_packed.
|
| - FAST_SMI_ELEMENTS, FAST_ELEMENTS,
|
| - // Handled by if_fast_holey.
|
| - FAST_HOLEY_SMI_ELEMENTS, FAST_HOLEY_ELEMENTS,
|
| - // Handled by if_fast_double.
|
| - FAST_DOUBLE_ELEMENTS,
|
| - // Handled by if_fast_holey_double.
|
| - FAST_HOLEY_DOUBLE_ELEMENTS};
|
| - Label* labels[] = {// FAST_{SMI,}_ELEMENTS
|
| - &if_fast_packed, &if_fast_packed,
|
| - // FAST_HOLEY_{SMI,}_ELEMENTS
|
| - &if_fast_holey, &if_fast_holey,
|
| - // FAST_DOUBLE_ELEMENTS
|
| - &if_fast_double,
|
| - // FAST_HOLEY_DOUBLE_ELEMENTS
|
| - &if_fast_holey_double};
|
| - Switch(elements_kind, &unimplemented_elements_kind, kinds, labels,
|
| - arraysize(kinds));
|
| - Bind(&unimplemented_elements_kind);
|
| - {
|
| - // Crash if we get here.
|
| - DebugBreak();
|
| - Goto(miss);
|
| - }
|
| -
|
| - Bind(&if_fast_packed);
|
| - {
|
| - Comment("fast packed elements");
|
| - // TODO(jkummerow): The Load*Element helpers add movsxlq instructions
|
| - // on x64 which we don't need here, because |key| is an IntPtr already.
|
| - // Do something about that.
|
| - Return(LoadFixedArrayElement(elements, key));
|
| - }
|
| -
|
| - Bind(&if_fast_holey);
|
| - {
|
| - Comment("fast holey elements");
|
| - Node* element = LoadFixedArrayElement(elements, key);
|
| - GotoIf(WordEqual(element, TheHoleConstant()), if_hole);
|
| - Return(element);
|
| - }
|
| -
|
| - Bind(&if_fast_double);
|
| - {
|
| - Comment("packed double elements");
|
| - var_double_value->Bind(
|
| - LoadFixedDoubleArrayElement(elements, key, MachineType::Float64()));
|
| - Goto(rebox_double);
|
| - }
|
| -
|
| - Bind(&if_fast_holey_double);
|
| - {
|
| - Comment("holey double elements");
|
| - if (kPointerSize == kDoubleSize) {
|
| - Node* raw_element =
|
| - LoadFixedDoubleArrayElement(elements, key, MachineType::Uint64());
|
| - Node* the_hole = Int64Constant(kHoleNanInt64);
|
| - GotoIf(Word64Equal(raw_element, the_hole), if_hole);
|
| - } else {
|
| - Node* element_upper = LoadFixedDoubleArrayElement(
|
| - elements, key, MachineType::Uint32(), kIeeeDoubleExponentWordOffset);
|
| - GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
|
| - if_hole);
|
| - }
|
| - var_double_value->Bind(
|
| - LoadFixedDoubleArrayElement(elements, key, MachineType::Float64()));
|
| - Goto(rebox_double);
|
| - }
|
| -
|
| - Bind(&if_typed_array);
|
| - {
|
| - Comment("typed elements");
|
| - // Check if buffer has been neutered.
|
| - Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
|
| - Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset,
|
| - MachineType::Uint32());
|
| - Node* neutered_bit =
|
| - Word32And(bitfield, Int32Constant(JSArrayBuffer::WasNeutered::kMask));
|
| - GotoUnless(Word32Equal(neutered_bit, Int32Constant(0)), miss);
|
| - // Backing store = external_pointer + base_pointer.
|
| - Node* external_pointer =
|
| - LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
|
| - MachineType::Pointer());
|
| - Node* base_pointer =
|
| - LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
|
| - Node* backing_store = IntPtrAdd(external_pointer, base_pointer);
|
| -
|
| - const int kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
|
| - FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
|
| - 1;
|
| - Label* elements_kind_labels[kTypedElementsKindCount];
|
| - int32_t elements_kinds[kTypedElementsKindCount];
|
| - for (int i = 0; i < kTypedElementsKindCount; i++) {
|
| - elements_kinds[i] = i + FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
|
| - elements_kind_labels[i] = new Label(this);
|
| - }
|
| - Switch(elements_kind, miss, elements_kinds, elements_kind_labels,
|
| - static_cast<size_t>(kTypedElementsKindCount));
|
| -
|
| - for (int i = 0; i < kTypedElementsKindCount; i++) {
|
| - ElementsKind kind = static_cast<ElementsKind>(elements_kinds[i]);
|
| - Bind(elements_kind_labels[i]);
|
| - Comment(ElementsKindToString(kind));
|
| - switch (kind) {
|
| - case UINT8_ELEMENTS:
|
| - case UINT8_CLAMPED_ELEMENTS:
|
| - Return(SmiTag(Load(MachineType::Uint8(), backing_store, key)));
|
| - break;
|
| - case INT8_ELEMENTS:
|
| - Return(SmiTag(Load(MachineType::Int8(), backing_store, key)));
|
| - break;
|
| - case UINT16_ELEMENTS: {
|
| - Node* index = WordShl(key, IntPtrConstant(1));
|
| - Return(SmiTag(Load(MachineType::Uint16(), backing_store, index)));
|
| - break;
|
| - }
|
| - case INT16_ELEMENTS: {
|
| - Node* index = WordShl(key, IntPtrConstant(1));
|
| - Return(SmiTag(Load(MachineType::Int16(), backing_store, index)));
|
| - break;
|
| - }
|
| - case UINT32_ELEMENTS: {
|
| - Node* index = WordShl(key, IntPtrConstant(2));
|
| - Node* element = Load(MachineType::Uint32(), backing_store, index);
|
| - Return(ChangeUint32ToTagged(element));
|
| - break;
|
| - }
|
| - case INT32_ELEMENTS: {
|
| - Node* index = WordShl(key, IntPtrConstant(2));
|
| - Node* element = Load(MachineType::Int32(), backing_store, index);
|
| - Return(ChangeInt32ToTagged(element));
|
| - break;
|
| - }
|
| - case FLOAT32_ELEMENTS: {
|
| - Node* index = WordShl(key, IntPtrConstant(2));
|
| - Node* element = Load(MachineType::Float32(), backing_store, index);
|
| - var_double_value->Bind(ChangeFloat32ToFloat64(element));
|
| - Goto(rebox_double);
|
| - break;
|
| - }
|
| - case FLOAT64_ELEMENTS: {
|
| - Node* index = WordShl(key, IntPtrConstant(3));
|
| - Node* element = Load(MachineType::Float64(), backing_store, index);
|
| - var_double_value->Bind(element);
|
| - Goto(rebox_double);
|
| - break;
|
| - }
|
| - default:
|
| - UNREACHABLE();
|
| - }
|
| - // Don't forget to clean up.
|
| - delete elements_kind_labels[i];
|
| - }
|
| - }
|
| -}
|
| -
|
| -void CodeStubAssembler::HandleLoadICHandlerCase(
|
| - const LoadICParameters* p, Node* handler, Label* miss,
|
| - ElementSupport support_elements) {
|
| +void CodeStubAssembler::HandleLoadICHandlerCase(const LoadICParameters* p,
|
| + Node* handler, Label* miss) {
|
| Comment("have_handler");
|
| Label call_handler(this);
|
| GotoUnless(WordIsSmi(handler), &call_handler);
|
|
|
| - // |handler| is a Smi, encoding what to do. See handler-configuration.h
|
| - // for the encoding format.
|
| + // |handler| is a Smi. It encodes a field index as obtained by
|
| + // FieldIndex.GetLoadByFieldOffset().
|
| + // TODO(jkummerow): For KeyedLoadICs, extend this scheme to encode
|
| + // fast *element* loads.
|
| {
|
| Variable var_double_value(this, MachineRepresentation::kFloat64);
|
| Label rebox_double(this, &var_double_value);
|
|
|
| Node* handler_word = SmiUntag(handler);
|
| - if (support_elements == kSupportElements) {
|
| - Label property(this);
|
| - Node* handler_type =
|
| - WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBit::kMask));
|
| - GotoUnless(
|
| - WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)),
|
| - &property);
|
| -
|
| - Comment("element_load");
|
| - GotoUnless(WordIsSmi(p->name), miss);
|
| - Node* key = SmiUntag(p->name);
|
| - Node* elements = LoadElements(p->receiver);
|
| - Node* is_jsarray =
|
| - WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask));
|
| - EmitBoundsCheck(p->receiver, elements, key, is_jsarray, miss);
|
| - Label if_hole(this);
|
| -
|
| - Node* elements_kind = BitFieldDecode<KeyedLoadElementsKind>(handler_word);
|
| -
|
| - EmitElementLoad(p->receiver, elements, elements_kind, key, &if_hole,
|
| - &rebox_double, &var_double_value, miss);
|
| -
|
| - Bind(&if_hole);
|
| - {
|
| - Comment("convert hole");
|
| - Node* convert_hole =
|
| - WordAnd(handler_word, IntPtrConstant(KeyedLoadConvertHole::kMask));
|
| - GotoIf(WordEqual(convert_hole, IntPtrConstant(0)), miss);
|
| - Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex);
|
| - GotoUnless(
|
| - WordEqual(LoadObjectField(protector_cell, Cell::kValueOffset),
|
| - SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))),
|
| - miss);
|
| - Return(UndefinedConstant());
|
| - }
|
| -
|
| - Bind(&property);
|
| - Comment("property_load");
|
| - }
|
| -
|
| // |handler_word| is a field index as obtained by
|
| // FieldIndex.GetLoadByFieldOffset():
|
| Label inobject_double(this), out_of_object(this),
|
| out_of_object_double(this);
|
| - Node* inobject_bit =
|
| - WordAnd(handler_word, IntPtrConstant(FieldOffsetIsInobject::kMask));
|
| - Node* double_bit =
|
| - WordAnd(handler_word, IntPtrConstant(FieldOffsetIsDouble::kMask));
|
| - Node* offset =
|
| - WordSar(handler_word, IntPtrConstant(FieldOffsetOffset::kShift));
|
| + Node* inobject_bit = WordAnd(
|
| + handler_word, IntPtrConstant(FieldIndex::FieldOffsetIsInobject::kMask));
|
| + Node* double_bit = WordAnd(
|
| + handler_word, IntPtrConstant(FieldIndex::FieldOffsetIsDouble::kMask));
|
| + Node* offset = WordSar(
|
| + handler_word, IntPtrConstant(FieldIndex::FieldOffsetOffset::kShift));
|
|
|
| GotoIf(WordEqual(inobject_bit, IntPtrConstant(0)), &out_of_object);
|
|
|
| @@ -3781,7 +3550,7 @@
|
| &var_handler, &try_polymorphic);
|
| Bind(&if_handler);
|
| {
|
| - HandleLoadICHandlerCase(p, var_handler.value(), &miss, kSupportElements);
|
| + HandleLoadICHandlerCase(p, var_handler.value(), &miss);
|
| }
|
|
|
| Bind(&try_polymorphic);
|
|
|