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

Side by Side Diff: src/hydrogen.cc

Issue 23030002: Simplified BuildFastLiteral by eliminating manual allocation folding. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4025 matching lines...) Expand 10 before | Expand all | Expand 10 after
4036 } 4036 }
4037 return false; 4037 return false;
4038 } 4038 }
4039 4039
4040 4040
4041 // Determines whether the given array or object literal boilerplate satisfies 4041 // Determines whether the given array or object literal boilerplate satisfies
4042 // all limits to be considered for fast deep-copying and computes the total 4042 // all limits to be considered for fast deep-copying and computes the total
4043 // size of all objects that are part of the graph. 4043 // size of all objects that are part of the graph.
4044 static bool IsFastLiteral(Handle<JSObject> boilerplate, 4044 static bool IsFastLiteral(Handle<JSObject> boilerplate,
4045 int max_depth, 4045 int max_depth,
4046 int* max_properties, 4046 int* max_properties) {
4047 int* data_size,
4048 int* pointer_size) {
4049 if (boilerplate->map()->is_deprecated()) { 4047 if (boilerplate->map()->is_deprecated()) {
4050 Handle<Object> result = JSObject::TryMigrateInstance(boilerplate); 4048 Handle<Object> result = JSObject::TryMigrateInstance(boilerplate);
4051 if (result->IsSmi()) return false; 4049 if (result->IsSmi()) return false;
4052 } 4050 }
4053 4051
4054 ASSERT(max_depth >= 0 && *max_properties >= 0); 4052 ASSERT(max_depth >= 0 && *max_properties >= 0);
4055 if (max_depth == 0) return false; 4053 if (max_depth == 0) return false;
4056 4054
4057 Isolate* isolate = boilerplate->GetIsolate(); 4055 Isolate* isolate = boilerplate->GetIsolate();
4058 Handle<FixedArrayBase> elements(boilerplate->elements()); 4056 Handle<FixedArrayBase> elements(boilerplate->elements());
4059 if (elements->length() > 0 && 4057 if (elements->length() > 0 &&
4060 elements->map() != isolate->heap()->fixed_cow_array_map()) { 4058 elements->map() != isolate->heap()->fixed_cow_array_map()) {
4061 if (boilerplate->HasFastDoubleElements()) { 4059 if (boilerplate->HasFastObjectElements()) {
4062 *data_size += FixedDoubleArray::SizeFor(elements->length());
4063 } else if (boilerplate->HasFastObjectElements()) {
4064 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 4060 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
4065 int length = elements->length(); 4061 int length = elements->length();
4066 for (int i = 0; i < length; i++) { 4062 for (int i = 0; i < length; i++) {
4067 if ((*max_properties)-- == 0) return false; 4063 if ((*max_properties)-- == 0) return false;
4068 Handle<Object> value(fast_elements->get(i), isolate); 4064 Handle<Object> value(fast_elements->get(i), isolate);
4069 if (value->IsJSObject()) { 4065 if (value->IsJSObject()) {
4070 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 4066 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
4071 if (!IsFastLiteral(value_object, 4067 if (!IsFastLiteral(value_object,
4072 max_depth - 1, 4068 max_depth - 1,
4073 max_properties, 4069 max_properties)) {
4074 data_size,
4075 pointer_size)) {
4076 return false; 4070 return false;
4077 } 4071 }
4078 } 4072 }
4079 } 4073 }
4080 *pointer_size += FixedArray::SizeFor(length);
4081 } else { 4074 } else {
4082 return false; 4075 return false;
4083 } 4076 }
4084 } 4077 }
4085 4078
4086 Handle<FixedArray> properties(boilerplate->properties()); 4079 Handle<FixedArray> properties(boilerplate->properties());
4087 if (properties->length() > 0) { 4080 if (properties->length() > 0) {
4088 return false; 4081 return false;
4089 } else { 4082 } else {
4090 Handle<DescriptorArray> descriptors( 4083 Handle<DescriptorArray> descriptors(
4091 boilerplate->map()->instance_descriptors()); 4084 boilerplate->map()->instance_descriptors());
4092 int limit = boilerplate->map()->NumberOfOwnDescriptors(); 4085 int limit = boilerplate->map()->NumberOfOwnDescriptors();
4093 for (int i = 0; i < limit; i++) { 4086 for (int i = 0; i < limit; i++) {
4094 PropertyDetails details = descriptors->GetDetails(i); 4087 PropertyDetails details = descriptors->GetDetails(i);
4095 if (details.type() != FIELD) continue; 4088 if (details.type() != FIELD) continue;
4096 Representation representation = details.representation();
4097 int index = descriptors->GetFieldIndex(i); 4089 int index = descriptors->GetFieldIndex(i);
4098 if ((*max_properties)-- == 0) return false; 4090 if ((*max_properties)-- == 0) return false;
4099 Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate); 4091 Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate);
4100 if (value->IsJSObject()) { 4092 if (value->IsJSObject()) {
4101 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 4093 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
4102 if (!IsFastLiteral(value_object, 4094 if (!IsFastLiteral(value_object,
4103 max_depth - 1, 4095 max_depth - 1,
4104 max_properties, 4096 max_properties)) {
4105 data_size,
4106 pointer_size)) {
4107 return false; 4097 return false;
4108 } 4098 }
4109 } else if (representation.IsDouble()) {
4110 *data_size += HeapNumber::kSize;
4111 } 4099 }
4112 } 4100 }
4113 } 4101 }
4114
4115 *pointer_size += boilerplate->map()->instance_size();
4116 return true; 4102 return true;
4117 } 4103 }
4118 4104
4119 4105
4120 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 4106 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
4121 ASSERT(!HasStackOverflow()); 4107 ASSERT(!HasStackOverflow());
4122 ASSERT(current_block() != NULL); 4108 ASSERT(current_block() != NULL);
4123 ASSERT(current_block()->HasPredecessor()); 4109 ASSERT(current_block()->HasPredecessor());
4124 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4110 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4125 HValue* context = environment()->context();
4126 HInstruction* literal; 4111 HInstruction* literal;
4127 4112
4128 // Check whether to use fast or slow deep-copying for boilerplate. 4113 // Check whether to use fast or slow deep-copying for boilerplate.
4129 int data_size = 0;
4130 int pointer_size = 0;
4131 int max_properties = kMaxFastLiteralProperties; 4114 int max_properties = kMaxFastLiteralProperties;
4132 Handle<Object> original_boilerplate(closure->literals()->get( 4115 Handle<Object> original_boilerplate(closure->literals()->get(
4133 expr->literal_index()), isolate()); 4116 expr->literal_index()), isolate());
4134 if (original_boilerplate->IsJSObject() && 4117 if (original_boilerplate->IsJSObject() &&
4135 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate), 4118 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate),
4136 kMaxFastLiteralDepth, 4119 kMaxFastLiteralDepth,
4137 &max_properties, 4120 &max_properties)) {
4138 &data_size,
4139 &pointer_size)) {
4140 Handle<JSObject> original_boilerplate_object = 4121 Handle<JSObject> original_boilerplate_object =
4141 Handle<JSObject>::cast(original_boilerplate); 4122 Handle<JSObject>::cast(original_boilerplate);
4142 Handle<JSObject> boilerplate_object = 4123 Handle<JSObject> boilerplate_object =
4143 DeepCopy(original_boilerplate_object); 4124 DeepCopy(original_boilerplate_object);
4144 4125
4145 literal = BuildFastLiteral(context, 4126 literal = BuildFastLiteral(boilerplate_object,
4146 boilerplate_object,
4147 original_boilerplate_object, 4127 original_boilerplate_object,
4148 Handle<Object>::null(), 4128 Handle<Object>::null(),
4149 data_size,
4150 pointer_size,
4151 DONT_TRACK_ALLOCATION_SITE); 4129 DONT_TRACK_ALLOCATION_SITE);
4152 } else { 4130 } else {
4153 NoObservableSideEffectsScope no_effects(this); 4131 NoObservableSideEffectsScope no_effects(this);
4154 Handle<FixedArray> closure_literals(closure->literals(), isolate()); 4132 Handle<FixedArray> closure_literals(closure->literals(), isolate());
4155 Handle<FixedArray> constant_properties = expr->constant_properties(); 4133 Handle<FixedArray> constant_properties = expr->constant_properties();
4156 int literal_index = expr->literal_index(); 4134 int literal_index = expr->literal_index();
4157 int flags = expr->fast_elements() 4135 int flags = expr->fast_elements()
4158 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; 4136 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags;
4159 flags |= expr->has_function() 4137 flags |= expr->has_function()
4160 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; 4138 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
4242 } 4220 }
4243 } 4221 }
4244 4222
4245 4223
4246 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 4224 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
4247 ASSERT(!HasStackOverflow()); 4225 ASSERT(!HasStackOverflow());
4248 ASSERT(current_block() != NULL); 4226 ASSERT(current_block() != NULL);
4249 ASSERT(current_block()->HasPredecessor()); 4227 ASSERT(current_block()->HasPredecessor());
4250 ZoneList<Expression*>* subexprs = expr->values(); 4228 ZoneList<Expression*>* subexprs = expr->values();
4251 int length = subexprs->length(); 4229 int length = subexprs->length();
4252 HValue* context = environment()->context();
4253 HInstruction* literal; 4230 HInstruction* literal;
4254 4231
4255 Handle<AllocationSite> site; 4232 Handle<AllocationSite> site;
4256 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 4233 Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
4257 bool uninitialized = false; 4234 bool uninitialized = false;
4258 Handle<Object> literals_cell(literals->get(expr->literal_index()), 4235 Handle<Object> literals_cell(literals->get(expr->literal_index()),
4259 isolate()); 4236 isolate());
4260 Handle<Object> raw_boilerplate; 4237 Handle<Object> raw_boilerplate;
4261 if (literals_cell->IsUndefined()) { 4238 if (literals_cell->IsUndefined()) {
4262 uninitialized = true; 4239 uninitialized = true;
(...skipping 25 matching lines...) Expand all
4288 ElementsKind boilerplate_elements_kind = 4265 ElementsKind boilerplate_elements_kind =
4289 Handle<JSObject>::cast(original_boilerplate_object)->GetElementsKind(); 4266 Handle<JSObject>::cast(original_boilerplate_object)->GetElementsKind();
4290 4267
4291 // TODO(mvstanton): This heuristic is only a temporary solution. In the 4268 // TODO(mvstanton): This heuristic is only a temporary solution. In the
4292 // end, we want to quit creating allocation site info after a certain number 4269 // end, we want to quit creating allocation site info after a certain number
4293 // of GCs for a call site. 4270 // of GCs for a call site.
4294 AllocationSiteMode mode = AllocationSite::GetMode( 4271 AllocationSiteMode mode = AllocationSite::GetMode(
4295 boilerplate_elements_kind); 4272 boilerplate_elements_kind);
4296 4273
4297 // Check whether to use fast or slow deep-copying for boilerplate. 4274 // Check whether to use fast or slow deep-copying for boilerplate.
4298 int data_size = 0;
4299 int pointer_size = 0;
4300 int max_properties = kMaxFastLiteralProperties; 4275 int max_properties = kMaxFastLiteralProperties;
4301 HCheckMaps* type_check = NULL; 4276 HCheckMaps* type_check = NULL;
4302 if (IsFastLiteral(original_boilerplate_object, 4277 if (IsFastLiteral(original_boilerplate_object,
4303 kMaxFastLiteralDepth, 4278 kMaxFastLiteralDepth,
4304 &max_properties, 4279 &max_properties)) {
4305 &data_size,
4306 &pointer_size)) {
4307 if (mode == TRACK_ALLOCATION_SITE) {
4308 pointer_size += AllocationMemento::kSize;
4309 }
4310
4311 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object); 4280 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object);
4312 literal = BuildFastLiteral(context, 4281 literal = BuildFastLiteral(boilerplate_object,
4313 boilerplate_object,
4314 original_boilerplate_object, 4282 original_boilerplate_object,
4315 site, 4283 site,
4316 data_size,
4317 pointer_size,
4318 mode); 4284 mode);
4319 } else { 4285 } else {
4320 NoObservableSideEffectsScope no_effects(this); 4286 NoObservableSideEffectsScope no_effects(this);
4321 // Boilerplate already exists and constant elements are never accessed, 4287 // Boilerplate already exists and constant elements are never accessed,
4322 // pass an empty fixed array to the runtime function instead. 4288 // pass an empty fixed array to the runtime function instead.
4323 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 4289 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
4324 int literal_index = expr->literal_index(); 4290 int literal_index = expr->literal_index();
4325 4291
4326 Add<HPushArgument>(Add<HConstant>(literals)); 4292 Add<HPushArgument>(Add<HConstant>(literals));
4327 Add<HPushArgument>(Add<HConstant>(literal_index)); 4293 Add<HPushArgument>(Add<HConstant>(literal_index));
(...skipping 3884 matching lines...) Expand 10 before | Expand all | Expand 10 after
8212 if (function_state()->outer() != NULL) { 8178 if (function_state()->outer() != NULL) {
8213 return New<HConstant>( 8179 return New<HConstant>(
8214 function_state()->compilation_info()->closure()); 8180 function_state()->compilation_info()->closure());
8215 } else { 8181 } else {
8216 return new(zone()) HThisFunction; 8182 return new(zone()) HThisFunction;
8217 } 8183 }
8218 } 8184 }
8219 8185
8220 8186
8221 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 8187 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
8222 HValue* context,
8223 Handle<JSObject> boilerplate_object,
8224 Handle<JSObject> original_boilerplate_object,
8225 Handle<Object> allocation_site,
8226 int data_size,
8227 int pointer_size,
8228 AllocationSiteMode mode) {
8229 NoObservableSideEffectsScope no_effects(this);
8230
8231 HInstruction* target = NULL;
8232 HInstruction* data_target = NULL;
8233
8234 if (isolate()->heap()->GetPretenureMode() == TENURED) {
8235 if (data_size != 0) {
8236 HValue* size_in_bytes = Add<HConstant>(data_size);
8237 data_target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED,
8238 FIXED_DOUBLE_ARRAY_TYPE);
8239 Handle<Map> free_space_map = isolate()->factory()->free_space_map();
8240 AddStoreMapConstant(data_target, free_space_map);
8241 HObjectAccess access =
8242 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
8243 Add<HStoreNamedField>(data_target, access, size_in_bytes);
8244 }
8245 if (pointer_size != 0) {
8246 HValue* size_in_bytes = Add<HConstant>(pointer_size);
8247 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED,
8248 JS_OBJECT_TYPE);
8249 }
8250 } else {
8251 InstanceType instance_type = boilerplate_object->map()->instance_type();
8252 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size);
8253 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), NOT_TENURED,
8254 instance_type);
8255 }
8256
8257 int offset = 0;
8258 int data_offset = 0;
8259 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object,
8260 allocation_site, target, &offset, data_target,
8261 &data_offset, mode);
8262 return target;
8263 }
8264
8265
8266 void HOptimizedGraphBuilder::BuildEmitDeepCopy(
8267 Handle<JSObject> boilerplate_object, 8188 Handle<JSObject> boilerplate_object,
8268 Handle<JSObject> original_boilerplate_object, 8189 Handle<JSObject> original_boilerplate_object,
Michael Starzinger 2013/08/16 20:18:56 Why does this function take the deep-copied boiler
Hannes Payer (out of office) 2013/08/22 13:27:23 Thanks for the comment, removed. Done.
8269 Handle<Object> allocation_site_object, 8190 Handle<Object> allocation_site_object,
8270 HInstruction* target,
8271 int* offset,
8272 HInstruction* data_target,
8273 int* data_offset,
8274 AllocationSiteMode mode) { 8191 AllocationSiteMode mode) {
8192 NoObservableSideEffectsScope no_effects(this);
8275 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && 8193 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
8276 boilerplate_object->map()->CanTrackAllocationSite(); 8194 boilerplate_object->map()->CanTrackAllocationSite();
8277 8195
8278 // If using allocation sites, then the payload on the site should already 8196 // If using allocation sites, then the payload on the site should already
8279 // be filled in as a valid (boilerplate) array. 8197 // be filled in as a valid (boilerplate) array.
8280 ASSERT(!create_allocation_site_info || 8198 ASSERT(!create_allocation_site_info ||
8281 AllocationSite::cast(*allocation_site_object)->IsLiteralSite()); 8199 AllocationSite::cast(*allocation_site_object)->IsLiteralSite());
8282 8200
8283 HInstruction* allocation_site = NULL;
8284
8285 if (create_allocation_site_info) {
8286 allocation_site = Add<HConstant>(allocation_site_object);
8287 }
8288
8289 // Only elements backing stores for non-COW arrays need to be copied.
8290 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 8201 Handle<FixedArrayBase> elements(boilerplate_object->elements());
8291 Handle<FixedArrayBase> original_elements( 8202 Handle<FixedArrayBase> original_elements(
8292 original_boilerplate_object->elements()); 8203 original_boilerplate_object->elements());
8293 ElementsKind kind = boilerplate_object->map()->elements_kind(); 8204 ElementsKind kind = boilerplate_object->map()->elements_kind();
8294 8205
8295 int object_offset = *offset;
8296 int object_size = boilerplate_object->map()->instance_size(); 8206 int object_size = boilerplate_object->map()->instance_size();
8207 int object_offset = object_size;
8208
8209 if (create_allocation_site_info) {
8210 object_size += AllocationMemento::kSize;
8211 }
8212
8213 HValue* object_size_constant = Add<HConstant>(object_size);
8214 HInstruction* object = Add<HAllocate>(object_size_constant, HType::JSObject(),
8215 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE);
8216
8217 if (create_allocation_site_info) {
8218 HInstruction* allocation_site = Add<HConstant>(allocation_site_object);
8219 BuildCreateAllocationMemento(object, object_offset, allocation_site);
8220 }
8221
8297 int elements_size = (elements->length() > 0 && 8222 int elements_size = (elements->length() > 0 &&
8298 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 8223 elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
8299 elements->Size() : 0; 8224 elements->Size() : 0;
8300 int elements_offset = 0; 8225 HInstruction* object_elements = NULL;
8301 8226 if (elements_size > 0) {
8302 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) { 8227 HValue* object_elements_size = Add<HConstant>(elements_size);
8303 elements_offset = *data_offset; 8228 if (boilerplate_object->HasFastDoubleElements()) {
8304 *data_offset += elements_size; 8229 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(),
8305 } else { 8230 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE);
8306 // Place elements right after this object. 8231 } else {
8307 elements_offset = *offset + object_size; 8232 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(),
8308 *offset += elements_size; 8233 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE);
8234 }
8309 } 8235 }
8310 // Increase the offset so that subsequent objects end up right after this
8311 // object (and it's elements if they are allocated in the same space).
8312 *offset += object_size;
8313 8236
8314 // Copy object elements if non-COW. 8237 // Copy object elements if non-COW.
8315 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, 8238 BuildEmitObjectHeader(boilerplate_object, object, object_elements);
8316 data_target, object_offset, elements_offset, elements_size);
8317 if (object_elements != NULL) { 8239 if (object_elements != NULL) {
8318 BuildEmitElements(elements, original_elements, kind, object_elements, 8240 BuildEmitElements(elements, original_elements, kind, object_elements);
8319 target, offset, data_target, data_offset);
8320 } 8241 }
8321 8242
8322 // Copy in-object properties. 8243 // Copy in-object properties.
8323 if (boilerplate_object->map()->NumberOfFields() != 0) { 8244 if (boilerplate_object->map()->NumberOfFields() != 0) {
8324 HValue* object_properties =
8325 Add<HInnerAllocatedObject>(target, object_offset);
8326 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, 8245 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object,
8327 object_properties, target, offset, data_target, data_offset); 8246 object);
8328 } 8247 }
8329 8248 return object;
8330 // Create allocation site info.
8331 if (mode == TRACK_ALLOCATION_SITE &&
8332 boilerplate_object->map()->CanTrackAllocationSite()) {
8333 elements_offset += AllocationMemento::kSize;
8334 *offset += AllocationMemento::kSize;
8335 BuildCreateAllocationMemento(target, JSArray::kSize, allocation_site);
8336 }
8337 } 8249 }
8338 8250
8339 8251
8340 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( 8252 void HOptimizedGraphBuilder::BuildEmitObjectHeader(
8341 Handle<JSObject> boilerplate_object, 8253 Handle<JSObject> boilerplate_object,
8342 HInstruction* target, 8254 HInstruction* object,
8343 HInstruction* data_target, 8255 HInstruction* object_elements) {
8344 int object_offset,
8345 int elements_offset,
8346 int elements_size) {
8347 ASSERT(boilerplate_object->properties()->length() == 0); 8256 ASSERT(boilerplate_object->properties()->length() == 0);
8348 HValue* result = NULL;
8349 8257
8350 HValue* object_header = Add<HInnerAllocatedObject>(target, object_offset);
8351 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 8258 Handle<Map> boilerplate_object_map(boilerplate_object->map());
8352 AddStoreMapConstant(object_header, boilerplate_object_map); 8259 AddStoreMapConstant(object, boilerplate_object_map);
8353 8260
8354 HInstruction* elements; 8261 if (object_elements == NULL) {
8355 if (elements_size == 0) {
8356 Handle<Object> elements_field = 8262 Handle<Object> elements_field =
8357 Handle<Object>(boilerplate_object->elements(), isolate()); 8263 Handle<Object>(boilerplate_object->elements(), isolate());
8358 elements = Add<HConstant>(elements_field); 8264 object_elements = Add<HConstant>(elements_field);
8359 } else {
8360 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
8361 elements = Add<HInnerAllocatedObject>(data_target, elements_offset);
8362 } else {
8363 elements = Add<HInnerAllocatedObject>(target, elements_offset);
8364 }
8365 result = elements;
8366 } 8265 }
8367 Add<HStoreNamedField>(object_header, HObjectAccess::ForElementsPointer(), 8266 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
8368 elements); 8267 object_elements);
8369 8268
8370 Handle<Object> properties_field = 8269 Handle<Object> properties_field =
8371 Handle<Object>(boilerplate_object->properties(), isolate()); 8270 Handle<Object>(boilerplate_object->properties(), isolate());
8372 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 8271 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
8373 HInstruction* properties = Add<HConstant>(properties_field); 8272 HInstruction* properties = Add<HConstant>(properties_field);
8374 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 8273 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
8375 Add<HStoreNamedField>(object_header, access, properties); 8274 Add<HStoreNamedField>(object, access, properties);
8376 8275
8377 if (boilerplate_object->IsJSArray()) { 8276 if (boilerplate_object->IsJSArray()) {
8378 Handle<JSArray> boilerplate_array = 8277 Handle<JSArray> boilerplate_array =
8379 Handle<JSArray>::cast(boilerplate_object); 8278 Handle<JSArray>::cast(boilerplate_object);
8380 Handle<Object> length_field = 8279 Handle<Object> length_field =
8381 Handle<Object>(boilerplate_array->length(), isolate()); 8280 Handle<Object>(boilerplate_array->length(), isolate());
8382 HInstruction* length = Add<HConstant>(length_field); 8281 HInstruction* length = Add<HConstant>(length_field);
8383 8282
8384 ASSERT(boilerplate_array->length()->IsSmi()); 8283 ASSERT(boilerplate_array->length()->IsSmi());
8385 Add<HStoreNamedField>(object_header, HObjectAccess::ForArrayLength( 8284 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
8386 boilerplate_array->GetElementsKind()), length); 8285 boilerplate_array->GetElementsKind()), length);
8387 } 8286 }
8388
8389 return result;
8390 } 8287 }
8391 8288
8392 8289
8393 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 8290 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
8394 Handle<JSObject> boilerplate_object, 8291 Handle<JSObject> boilerplate_object,
8395 Handle<JSObject> original_boilerplate_object, 8292 Handle<JSObject> original_boilerplate_object,
Michael Starzinger 2013/08/16 20:18:56 Likewise.
Hannes Payer (out of office) 2013/08/22 13:27:23 Done.
8396 HValue* object_properties, 8293 HInstruction* object) {
8397 HInstruction* target,
8398 int* offset,
8399 HInstruction* data_target,
8400 int* data_offset) {
8401 Handle<DescriptorArray> descriptors( 8294 Handle<DescriptorArray> descriptors(
8402 boilerplate_object->map()->instance_descriptors()); 8295 boilerplate_object->map()->instance_descriptors());
8403 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); 8296 int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
8404 8297
8405 int copied_fields = 0; 8298 int copied_fields = 0;
8406 for (int i = 0; i < limit; i++) { 8299 for (int i = 0; i < limit; i++) {
8407 PropertyDetails details = descriptors->GetDetails(i); 8300 PropertyDetails details = descriptors->GetDetails(i);
8408 if (details.type() != FIELD) continue; 8301 if (details.type() != FIELD) continue;
8409 copied_fields++; 8302 copied_fields++;
8410 int index = descriptors->GetFieldIndex(i); 8303 int index = descriptors->GetFieldIndex(i);
8411 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); 8304 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index);
8412 Handle<Name> name(descriptors->GetKey(i)); 8305 Handle<Name> name(descriptors->GetKey(i));
8413 Handle<Object> value = 8306 Handle<Object> value =
8414 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), 8307 Handle<Object>(boilerplate_object->InObjectPropertyAt(index),
8415 isolate()); 8308 isolate());
8416 8309
8417 // The access for the store depends on the type of the boilerplate. 8310 // The access for the store depends on the type of the boilerplate.
8418 HObjectAccess access = boilerplate_object->IsJSArray() ? 8311 HObjectAccess access = boilerplate_object->IsJSArray() ?
8419 HObjectAccess::ForJSArrayOffset(property_offset) : 8312 HObjectAccess::ForJSArrayOffset(property_offset) :
8420 HObjectAccess::ForJSObjectOffset(property_offset); 8313 HObjectAccess::ForJSObjectOffset(property_offset);
8421 8314
8422 if (value->IsJSObject()) { 8315 if (value->IsJSObject()) {
8423 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 8316 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
8424 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 8317 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
8425 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), 8318 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index),
8426 isolate())); 8319 isolate()));
8427 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, 8320 HInstruction* result =
8428 *offset); 8321 BuildFastLiteral(value_object, original_value_object,
8429 8322 Handle<Object>::null(), DONT_TRACK_ALLOCATION_SITE);
8430 Add<HStoreNamedField>(object_properties, access, value_instruction); 8323 Add<HStoreNamedField>(object, access, result);
8431 BuildEmitDeepCopy(value_object, original_value_object,
8432 Handle<Object>::null(), target,
8433 offset, data_target, data_offset,
8434 DONT_TRACK_ALLOCATION_SITE);
8435 } else { 8324 } else {
8436 Representation representation = details.representation(); 8325 Representation representation = details.representation();
8437 HInstruction* value_instruction = Add<HConstant>(value); 8326 HInstruction* value_instruction = Add<HConstant>(value);
8438 8327
8439 if (representation.IsDouble()) { 8328 if (representation.IsDouble()) {
8440 // Allocate a HeapNumber box and store the value into it. 8329 // Allocate a HeapNumber box and store the value into it.
8441 HInstruction* double_box; 8330 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize);
8442 if (data_target != NULL) { 8331 HInstruction* double_box =
8443 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); 8332 Add<HAllocate>(heap_number_constant, HType::HeapNumber(),
8444 *data_offset += HeapNumber::kSize; 8333 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE);
8445 } else {
8446 double_box = Add<HInnerAllocatedObject>(target, *offset);
8447 *offset += HeapNumber::kSize;
8448 }
8449 AddStoreMapConstant(double_box, 8334 AddStoreMapConstant(double_box,
8450 isolate()->factory()->heap_number_map()); 8335 isolate()->factory()->heap_number_map());
8451 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), 8336 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
8452 value_instruction); 8337 value_instruction);
8453 value_instruction = double_box; 8338 value_instruction = double_box;
8454 } 8339 }
8455 8340
8456 Add<HStoreNamedField>(object_properties, access, value_instruction); 8341 Add<HStoreNamedField>(object, access, value_instruction);
8457 } 8342 }
8458 } 8343 }
8459 8344
8460 int inobject_properties = boilerplate_object->map()->inobject_properties(); 8345 int inobject_properties = boilerplate_object->map()->inobject_properties();
8461 HInstruction* value_instruction = 8346 HInstruction* value_instruction =
8462 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 8347 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
8463 for (int i = copied_fields; i < inobject_properties; i++) { 8348 for (int i = copied_fields; i < inobject_properties; i++) {
8464 ASSERT(boilerplate_object->IsJSObject()); 8349 ASSERT(boilerplate_object->IsJSObject());
8465 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 8350 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
8466 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); 8351 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
8467 Add<HStoreNamedField>(object_properties, access, value_instruction); 8352 Add<HStoreNamedField>(object, access, value_instruction);
8468 } 8353 }
8469 } 8354 }
8470 8355
8471 8356
8472 void HOptimizedGraphBuilder::BuildEmitElements( 8357 void HOptimizedGraphBuilder::BuildEmitElements(
8473 Handle<FixedArrayBase> elements, 8358 Handle<FixedArrayBase> elements,
8474 Handle<FixedArrayBase> original_elements, 8359 Handle<FixedArrayBase> original_elements,
Michael Starzinger 2013/08/16 20:18:56 Likewise.
Hannes Payer (out of office) 2013/08/22 13:27:23 Done.
8475 ElementsKind kind, 8360 ElementsKind kind,
8476 HValue* object_elements, 8361 HValue* object_elements) {
8477 HInstruction* target,
8478 int* offset,
8479 HInstruction* data_target,
8480 int* data_offset) {
8481 int elements_length = elements->length(); 8362 int elements_length = elements->length();
8482 HValue* object_elements_length = Add<HConstant>(elements_length); 8363 HValue* object_elements_length = Add<HConstant>(elements_length);
8483
8484 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); 8364 BuildInitializeElementsHeader(object_elements, kind, object_elements_length);
8485 8365
8486 // Copy elements backing store content. 8366 // Copy elements backing store content.
8487 if (elements->IsFixedDoubleArray()) { 8367 if (elements->IsFixedDoubleArray()) {
8488 BuildEmitFixedDoubleArray(elements, kind, object_elements); 8368 BuildEmitFixedDoubleArray(elements, kind, object_elements);
8489 } else if (elements->IsFixedArray()) { 8369 } else if (elements->IsFixedArray()) {
8490 BuildEmitFixedArray(elements, original_elements, kind, object_elements, 8370 BuildEmitFixedArray(elements, original_elements, kind, object_elements);
8491 target, offset, data_target, data_offset);
8492 } else { 8371 } else {
8493 UNREACHABLE(); 8372 UNREACHABLE();
8494 } 8373 }
8495 } 8374 }
8496 8375
8497 8376
8498 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( 8377 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
8499 Handle<FixedArrayBase> elements, 8378 Handle<FixedArrayBase> elements,
8500 ElementsKind kind, 8379 ElementsKind kind,
8501 HValue* object_elements) { 8380 HValue* object_elements) {
8502 HInstruction* boilerplate_elements = Add<HConstant>(elements); 8381 HInstruction* boilerplate_elements = Add<HConstant>(elements);
8503 int elements_length = elements->length(); 8382 int elements_length = elements->length();
8504 for (int i = 0; i < elements_length; i++) { 8383 for (int i = 0; i < elements_length; i++) {
8505 HValue* key_constant = Add<HConstant>(i); 8384 HValue* key_constant = Add<HConstant>(i);
8506 HInstruction* value_instruction = 8385 HInstruction* value_instruction =
8507 Add<HLoadKeyed>(boilerplate_elements, key_constant, 8386 Add<HLoadKeyed>(boilerplate_elements, key_constant,
8508 static_cast<HValue*>(NULL), kind, 8387 static_cast<HValue*>(NULL), kind,
8509 ALLOW_RETURN_HOLE); 8388 ALLOW_RETURN_HOLE);
8510 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, 8389 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant,
8511 value_instruction, kind); 8390 value_instruction, kind);
8512 store->SetFlag(HValue::kAllowUndefinedAsNaN); 8391 store->SetFlag(HValue::kAllowUndefinedAsNaN);
8513 } 8392 }
8514 } 8393 }
8515 8394
8516 8395
8517 void HOptimizedGraphBuilder::BuildEmitFixedArray( 8396 void HOptimizedGraphBuilder::BuildEmitFixedArray(
8518 Handle<FixedArrayBase> elements, 8397 Handle<FixedArrayBase> elements,
8519 Handle<FixedArrayBase> original_elements, 8398 Handle<FixedArrayBase> original_elements,
Michael Starzinger 2013/08/16 20:18:56 Likewise.
Hannes Payer (out of office) 2013/08/22 13:27:23 Done.
8520 ElementsKind kind, 8399 ElementsKind kind,
8521 HValue* object_elements, 8400 HValue* object_elements) {
8522 HInstruction* target,
8523 int* offset,
8524 HInstruction* data_target,
8525 int* data_offset) {
8526 HInstruction* boilerplate_elements = Add<HConstant>(elements); 8401 HInstruction* boilerplate_elements = Add<HConstant>(elements);
8527 int elements_length = elements->length(); 8402 int elements_length = elements->length();
8528 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 8403 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
8529 Handle<FixedArray> original_fast_elements = 8404 Handle<FixedArray> original_fast_elements =
8530 Handle<FixedArray>::cast(original_elements); 8405 Handle<FixedArray>::cast(original_elements);
8531 for (int i = 0; i < elements_length; i++) { 8406 for (int i = 0; i < elements_length; i++) {
8532 Handle<Object> value(fast_elements->get(i), isolate()); 8407 Handle<Object> value(fast_elements->get(i), isolate());
8533 HValue* key_constant = Add<HConstant>(i); 8408 HValue* key_constant = Add<HConstant>(i);
8534 if (value->IsJSObject()) { 8409 if (value->IsJSObject()) {
8535 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 8410 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
8536 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 8411 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
8537 Handle<Object>(original_fast_elements->get(i), isolate())); 8412 Handle<Object>(original_fast_elements->get(i), isolate()));
8538 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, 8413 HInstruction* result =
8539 *offset); 8414 BuildFastLiteral(value_object, original_value_object,
8540 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); 8415 Handle<Object>::null(), DONT_TRACK_ALLOCATION_SITE);
8541 BuildEmitDeepCopy(value_object, original_value_object, 8416 Add<HStoreKeyed>(object_elements, key_constant, result, kind);
8542 Handle<Object>::null(), target,
8543 offset, data_target, data_offset,
8544 DONT_TRACK_ALLOCATION_SITE);
8545 } else { 8417 } else {
8546 HInstruction* value_instruction = 8418 HInstruction* value_instruction =
8547 Add<HLoadKeyed>(boilerplate_elements, key_constant, 8419 Add<HLoadKeyed>(boilerplate_elements, key_constant,
8548 static_cast<HValue*>(NULL), kind, 8420 static_cast<HValue*>(NULL), kind,
8549 ALLOW_RETURN_HOLE); 8421 ALLOW_RETURN_HOLE);
8550 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); 8422 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
8551 } 8423 }
8552 } 8424 }
8553 } 8425 }
8554 8426
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after
9829 if (ShouldProduceTraceOutput()) { 9701 if (ShouldProduceTraceOutput()) {
9830 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9702 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9831 } 9703 }
9832 9704
9833 #ifdef DEBUG 9705 #ifdef DEBUG
9834 graph_->Verify(false); // No full verify. 9706 graph_->Verify(false); // No full verify.
9835 #endif 9707 #endif
9836 } 9708 }
9837 9709
9838 } } // namespace v8::internal 9710 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698