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

Unified Diff: src/hydrogen.cc

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More efficient code when number of arguments is known Created 7 years, 8 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
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 5e36f68684f28e9556b8e90e2cbbc9d1253c36d4..1914faec9ba439834ff63276f9ed32c6ea2b29fd 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1329,8 +1329,8 @@ HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
Handle<Map> map,
BailoutId id) {
Zone* zone = this->zone();
- HValue* map_constant =
- AddInstruction(new(zone) HConstant(map, Representation::Tagged()));
+ HConstant* map_constant = new(zone) HConstant(map, Representation::Tagged());
+ AddInstruction(map_constant);
return BuildStoreMap(object, map_constant, id);
}
@@ -1590,6 +1590,257 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
}
+HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
+ ElementsKind kind,
+ HValue* allocation_site_payload) :
+ builder_(builder),
+ kind_(kind),
+ allocation_site_payload_(allocation_site_payload) {
+ // Determine mode
+ mode_ = AllocationSiteInfo::GetMode(kind);
+}
+
+
+HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
+ // Get the global context, the native context, the map array
+ HInstruction* global_object = AddInstruction(new(zone())
+ HGlobalObject(context));
+ HInstruction* native_context = AddInstruction(new(zone())
+ HLoadNamedField(global_object, true, GlobalObject::kNativeContextOffset));
+ size_t offset = Context::kHeaderSize +
+ kPointerSize * Context::JS_ARRAY_MAPS_INDEX;
+ HInstruction* map_array = AddInstruction(new(zone())
+ HLoadNamedField(native_context, true, offset));
+ offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize;
+ return AddInstruction(new(zone()) HLoadNamedField(map_array, true, offset));
+}
+
+
+HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
+ HValue* length_node) {
+ HValue* context = builder()->environment()->LookupContext();
+ ASSERT(length_node != NULL);
+
+ int base_size = JSArray::kSize;
+ if (mode_ == TRACK_ALLOCATION_SITE) {
+ base_size += AllocationSiteInfo::kSize;
+ }
+
+ if (IsFastDoubleElementsKind(kind_)) {
+ base_size += FixedDoubleArray::kHeaderSize;
+ } else {
+ base_size += FixedArray::kHeaderSize;
+ }
+
+ HInstruction* elements_size_value = new(zone())
+ HConstant(elements_size(), Representation::Integer32());
+ AddInstruction(elements_size_value);
+ HInstruction* mul = HMul::New(zone(), context, length_node,
+ elements_size_value);
+ mul->ChangeRepresentation(Representation::Integer32());
+ mul->ClearFlag(HValue::kCanOverflow);
+ AddInstruction(mul);
+ AddSimulate();
+
+ HInstruction* base = new(zone()) HConstant(base_size,
+ Representation::Integer32());
+ AddInstruction(base);
+ HInstruction* total_size = HAdd::New(zone(), context, base, mul);
+ total_size->ChangeRepresentation(Representation::Integer32());
+ total_size->ClearFlag(HValue::kCanOverflow);
+ AddInstruction(total_size);
+ AddSimulate();
+ return total_size;
+}
+
+
+HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
+ int base_size = JSArray::kSize;
+ if (mode_ == TRACK_ALLOCATION_SITE) {
+ base_size += AllocationSiteInfo::kSize;
+ }
+
+ if (initial_capacity() > 0) {
+ base_size += IsFastDoubleElementsKind(kind_)
+ ? FixedDoubleArray::SizeFor(initial_capacity())
+ : FixedArray::SizeFor(initial_capacity());
+ }
+
+ HConstant* array_size =
+ new(zone()) HConstant(base_size, Representation::Integer32());
+ AddInstruction(array_size);
+ return array_size;
+}
+
+
+HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
+ HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
+ HConstant* capacity =
+ new(zone()) HConstant(initial_capacity(), Representation::Integer32());
+ AddInstruction(capacity);
+ return AllocateArray(size_in_bytes, capacity, NULL, true);
+}
+
+
+HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
+ HValue* capacity,
+ HValue* length_field,
+ bool fill_with_hole) {
+ HValue* context = builder()->environment()->LookupContext();
+ Isolate* isolate = builder()->graph()->isolate();
mvstanton 2013/04/15 15:14:49 Hannes: How about for symmetry with BuildCopyObjec
mvstanton 2013/04/16 11:48:52 Done. And I continued in this spirit, finding seve
+
+ // Allocate (dealing with failure appropriately)
+ HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
+ if (IsFastDoubleElementsKind(kind_)) {
+ flags = static_cast<HAllocate::Flags>(
+ flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
+ }
+
+ HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes,
mvstanton 2013/04/15 15:14:49 Hannes: How about if HAllocate deals with the ALLO
mvstanton 2013/04/16 11:48:52 I made a useful helper function to improve this. I
+ HType::JSArray(), flags);
+ AddInstruction(new_object);
+
+ // Fill in the fields: map, properties, length
+ HValue* map = EmitMapCode(context);
+ builder()->BuildStoreMap(new_object, map, BailoutId::StubEntry());
+
+ HConstant* empty_fixed_array =
+ new(zone()) HConstant(
+ Handle<FixedArray>(isolate->heap()->empty_fixed_array()),
+ Representation::Tagged());
+ AddInstruction(empty_fixed_array);
+
+ AddInstruction(new(zone()) HStoreNamedField(new_object,
+ isolate->factory()->properties_field_symbol(),
+ empty_fixed_array,
+ true,
+ JSArray::kPropertiesOffset));
+ AddSimulate(FIXED_SIMULATE);
+
+ HValue* zero = builder()->graph()->GetConstant0();
+ HValue* array_length_field = zero;
+ if (length_field != NULL) {
+ array_length_field = length_field;
+ }
+ AddInstruction(new(zone()) HStoreNamedField(new_object,
+ isolate->factory()->length_field_string(),
+ array_length_field,
+ true,
+ JSArray::kLengthOffset));
+ AddSimulate(FIXED_SIMULATE);
+
+ if (mode_ == TRACK_ALLOCATION_SITE) {
mvstanton 2013/04/15 15:14:49 Hannes: Factor this out to combine with the piece
mvstanton 2013/04/16 11:48:52 Done.
+ // Fill in the payload
+ HInnerAllocatedObject* allocation_info_site = new(zone())
+ HInnerAllocatedObject(new_object, JSArray::kSize);
+ AddInstruction(allocation_info_site);
+ builder()->BuildStoreMap(allocation_info_site,
+ Handle<Map>(isolate->heap()->allocation_site_info_map()),
+ BailoutId::StubEntry());
+ AddInstruction(new(zone()) HStoreNamedField(allocation_info_site,
+ isolate->factory()->payload_field_symbol(),
+ allocation_site_payload_,
+ true,
+ AllocationSiteInfo::kPayloadOffset));
+ AddSimulate(FIXED_SIMULATE);
+ }
+
+ if (length_field == NULL && initial_capacity() == 0) {
+ AddInstruction(new(zone()) HStoreNamedField(new_object,
+ isolate->factory()->elements_field_string(),
+ empty_fixed_array,
+ true,
+ JSArray::kElementsOffset));
+ AddSimulate(FIXED_SIMULATE);
+ } else {
+ int elements_location = JSArray::kSize;
+ if (mode_ == TRACK_ALLOCATION_SITE) {
+ elements_location += AllocationSiteInfo::kSize;
+ }
+
+ elements_location_ = new(zone()) HInnerAllocatedObject(new_object,
+ elements_location);
+ AddInstruction(elements_location_);
+
+ AddInstruction(new(zone()) HStoreNamedField(new_object,
+ isolate->factory()->elements_field_string(),
+ elements_location_,
+ true,
+ JSArray::kElementsOffset));
+ AddSimulate(FIXED_SIMULATE);
+
+ // Initialize the elements
+ Handle<Map> map_elements = IsFastDoubleElementsKind(kind_)
+ ? isolate->factory()->fixed_double_array_map()
+ : isolate->factory()->fixed_array_map();
+ builder()->BuildStoreMap(elements_location_, map_elements,
+ BailoutId::StubEntry());
+
+ Handle<String> fixed_array_length_field_name =
+ isolate->factory()->length_field_string();
+ HInstruction* store_length =
+ new(zone()) HStoreNamedField(elements_location_,
+ fixed_array_length_field_name,
+ capacity,
+ true,
+ FixedArray::kLengthOffset);
+ AddInstruction(store_length);
+ AddSimulate(FIXED_SIMULATE);
+
+ if (fill_with_hole) {
+ FillWithHole(capacity, length_field == NULL);
+ }
+ }
+
+ return new_object;
+}
+
+
+void HGraphBuilder::JSArrayBuilder::FillWithHole(HValue* capacity,
+ bool nominally_empty) {
+ Isolate* isolate = builder()->graph()->isolate();
+ HValue* context = builder()->environment()->LookupContext();
+ double nan_double = FixedDoubleArray::hole_nan_as_double();
+ HConstant* hole = (IsFastSmiElementsKind(kind_) ||
+ IsFastObjectElementsKind(kind_))
mvstanton 2013/04/15 15:14:49 lines above replace with IsFastDoubleElementsKind(
mvstanton 2013/04/16 11:48:52 Done. Actually I could merge this function with an
+ ? new(zone()) HConstant(isolate->factory()->the_hole_value(),
+ Representation::Tagged())
+ : new(zone()) HConstant(nan_double, Representation::Double());
+
+ AddInstruction(hole);
+
+ static const int kLoopUnfoldLimit = 4;
+ if (nominally_empty && initial_capacity() <= kLoopUnfoldLimit) {
mvstanton 2013/04/15 15:14:49 move kLoopUnfoldLimit up to initial_capacity() def
+ for (int i = 0; i < initial_capacity(); i ++) {
+ HInstruction* key;
+ if (i == 0) {
+ key = graph()->GetConstant0();
+ } else if (i == 1) {
+ key = graph()->GetConstant1();
+ } else {
+ key = AddInstruction(new(zone())
+ HConstant(i, Representation::Integer32()));
+ }
+ AddInstruction(new(zone()) HStoreKeyed(elements_location_, key, hole,
+ kind_));
+ AddSimulate(REMOVABLE_SIMULATE);
+ }
+ } else {
+ LoopBuilder loop_builder(builder(),
+ context,
+ LoopBuilder::kPostIncrement);
+ HValue* zero = graph()->GetConstant0();
+ HValue* start = zero;
+ HValue* key = loop_builder.BeginBody(start, capacity, Token::LT);
+
+ AddInstruction(new(zone()) HStoreKeyed(elements_location_, key, hole,
+ kind_));
+ AddSimulate(REMOVABLE_SIMULATE);
+ loop_builder.EndBody();
+ }
+}
+
+
HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
TypeFeedbackOracle* oracle)
: HGraphBuilder(info),
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/builtins-ia32.cc » ('j') | src/ia32/code-stubs-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698