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

Unified Diff: src/ic/accessor-assembler.cc

Issue 2619823005: [ic][stubs] Move more IC-related methods from CSA to AccessorAssembler. (Closed)
Patch Set: Code reshuffling Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stub-assembler.cc ('k') | src/ic/accessor-assembler-impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/accessor-assembler.cc
diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc
index 6a27045f1228311a235692e01b87386898a36c09..22ecec2bb1462880d49c473d098a8c2b08f4e417 100644
--- a/src/ic/accessor-assembler.cc
+++ b/src/ic/accessor-assembler.cc
@@ -670,25 +670,9 @@ void AccessorAssemblerImpl::HandleStoreICSmiHandlerCase(Node* handler_word,
Bind(&if_heap_object_field);
{
Comment("store heap object field");
- // Generate full field type check here and then store value as Tagged.
- Node* prepared_value =
- PrepareValueForWrite(value, Representation::HeapObject(), miss);
- Node* value_index_in_descriptor =
- DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
- Node* descriptors =
- LoadMapDescriptors(transition ? transition : LoadMap(holder));
- Node* maybe_field_type =
- LoadFixedArrayElement(descriptors, value_index_in_descriptor);
- Label do_store(this);
- GotoIf(TaggedIsSmi(maybe_field_type), &do_store);
- // Check that value type matches the field type.
- {
- Node* field_type = LoadWeakCellValue(maybe_field_type, miss);
- Branch(WordEqual(LoadMap(prepared_value), field_type), &do_store, miss);
- }
- Bind(&do_store);
- HandleStoreFieldAndReturn(handler_word, holder, Representation::Tagged(),
- prepared_value, transition, miss);
+ HandleStoreFieldAndReturn(handler_word, holder,
+ Representation::HeapObject(), value, transition,
+ miss);
}
Bind(&if_smi_field);
@@ -703,19 +687,8 @@ void AccessorAssemblerImpl::HandleStoreFieldAndReturn(
Node* handler_word, Node* holder, Representation representation,
Node* value, Node* transition, Label* miss) {
bool transition_to_field = transition != nullptr;
- Node* prepared_value = PrepareValueForWrite(value, representation, miss);
-
- if (transition_to_field) {
- Label storage_extended(this);
- GotoUnless(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word),
- &storage_extended);
- Comment("[ Extend storage");
- ExtendPropertiesBackingStore(holder);
- Comment("] Extend storage");
- Goto(&storage_extended);
-
- Bind(&storage_extended);
- }
+ Node* prepared_value = PrepareValueForStore(
+ handler_word, holder, representation, transition, value, miss);
Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word);
Label if_inobject(this), if_out_of_object(this);
@@ -734,6 +707,18 @@ void AccessorAssemblerImpl::HandleStoreFieldAndReturn(
Bind(&if_out_of_object);
{
+ if (transition_to_field) {
+ Label storage_extended(this);
+ GotoUnless(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word),
+ &storage_extended);
+ Comment("[ Extend storage");
+ ExtendPropertiesBackingStore(holder);
+ Comment("] Extend storage");
+ Goto(&storage_extended);
+
+ Bind(&storage_extended);
+ }
+
StoreNamedField(holder, offset, false, representation, prepared_value,
transition_to_field);
if (transition_to_field) {
@@ -743,6 +728,114 @@ void AccessorAssemblerImpl::HandleStoreFieldAndReturn(
}
}
+Node* AccessorAssemblerImpl::PrepareValueForStore(Node* handler_word,
+ Node* holder,
+ Representation representation,
+ Node* transition, Node* value,
+ Label* bailout) {
+ if (representation.IsDouble()) {
+ value = TryTaggedToFloat64(value, bailout);
+
+ } else if (representation.IsHeapObject()) {
+ GotoIf(TaggedIsSmi(value), bailout);
+ Node* value_index_in_descriptor =
+ DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
+ Node* descriptors =
+ LoadMapDescriptors(transition ? transition : LoadMap(holder));
+ Node* maybe_field_type =
+ LoadFixedArrayElement(descriptors, value_index_in_descriptor);
+
+ Label done(this);
+ GotoIf(TaggedIsSmi(maybe_field_type), &done);
+ // Check that value type matches the field type.
+ {
+ Node* field_type = LoadWeakCellValue(maybe_field_type, bailout);
+ Branch(WordEqual(LoadMap(value), field_type), &done, bailout);
+ }
+ Bind(&done);
+
+ } else if (representation.IsSmi()) {
+ GotoUnless(TaggedIsSmi(value), bailout);
+
+ } else {
+ DCHECK(representation.IsTagged());
+ }
+ return value;
+}
+
+void AccessorAssemblerImpl::ExtendPropertiesBackingStore(Node* object) {
+ Node* properties = LoadProperties(object);
+ Node* length = LoadFixedArrayBaseLength(properties);
+
+ ParameterMode mode = OptimalParameterMode();
+ length = TaggedToParameter(length, mode);
+
+ Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode);
+ Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode);
+
+ // Grow properties array.
+ ElementsKind kind = FAST_ELEMENTS;
+ DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded <
+ FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind));
+ // The size of a new properties backing store is guaranteed to be small
+ // enough that the new backing store will be allocated in new space.
+ CSA_ASSERT(this,
+ UintPtrOrSmiLessThan(
+ new_capacity,
+ IntPtrOrSmiConstant(
+ kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode),
+ mode));
+
+ Node* new_properties = AllocateFixedArray(kind, new_capacity, mode);
+
+ FillFixedArrayWithValue(kind, new_properties, length, new_capacity,
+ Heap::kUndefinedValueRootIndex, mode);
+
+ // |new_properties| is guaranteed to be in new space, so we can skip
+ // the write barrier.
+ CopyFixedArrayElements(kind, properties, new_properties, length,
+ SKIP_WRITE_BARRIER, mode);
+
+ StoreObjectField(object, JSObject::kPropertiesOffset, new_properties);
+}
+
+void AccessorAssemblerImpl::StoreNamedField(Node* object, Node* offset,
+ bool is_inobject,
+ Representation representation,
+ Node* value,
+ bool transition_to_field) {
+ bool store_value_as_double = representation.IsDouble();
+ Node* property_storage = object;
+ if (!is_inobject) {
+ property_storage = LoadProperties(object);
+ }
+
+ if (representation.IsDouble()) {
+ if (!FLAG_unbox_double_fields || !is_inobject) {
+ if (transition_to_field) {
+ Node* heap_number = AllocateHeapNumberWithValue(value, MUTABLE);
+ // Store the new mutable heap number into the object.
+ value = heap_number;
+ store_value_as_double = false;
+ } else {
+ // Load the heap number.
+ property_storage = LoadObjectField(property_storage, offset);
+ // Store the double value into it.
+ offset = IntPtrConstant(HeapNumber::kValueOffset);
+ }
+ }
+ }
+
+ if (store_value_as_double) {
+ StoreObjectFieldNoWriteBarrier(property_storage, offset, value,
+ MachineRepresentation::kFloat64);
+ } else if (representation.IsSmi()) {
+ StoreObjectFieldNoWriteBarrier(property_storage, offset, value);
+ } else {
+ StoreObjectField(property_storage, offset, value);
+ }
+}
+
void AccessorAssemblerImpl::EmitFastElementsBoundsCheck(
Node* object, Node* elements, Node* intptr_index,
Node* is_jsarray_condition, Label* miss) {
« no previous file with comments | « src/code-stub-assembler.cc ('k') | src/ic/accessor-assembler-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698