| OLD | NEW |
| 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 12 matching lines...) Expand all Loading... |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "hydrogen.h" | 28 #include "hydrogen.h" |
| 29 | 29 |
| 30 #include <algorithm> | 30 #include <algorithm> |
| 31 | 31 |
| 32 #include "v8.h" | 32 #include "v8.h" |
| 33 #include "allocation-site-scopes.h" |
| 33 #include "codegen.h" | 34 #include "codegen.h" |
| 34 #include "full-codegen.h" | 35 #include "full-codegen.h" |
| 35 #include "hashmap.h" | 36 #include "hashmap.h" |
| 36 #include "hydrogen-bce.h" | 37 #include "hydrogen-bce.h" |
| 37 #include "hydrogen-bch.h" | 38 #include "hydrogen-bch.h" |
| 38 #include "hydrogen-canonicalize.h" | 39 #include "hydrogen-canonicalize.h" |
| 39 #include "hydrogen-check-elimination.h" | 40 #include "hydrogen-check-elimination.h" |
| 40 #include "hydrogen-dce.h" | 41 #include "hydrogen-dce.h" |
| 41 #include "hydrogen-dehoist.h" | 42 #include "hydrogen-dehoist.h" |
| 42 #include "hydrogen-environment-liveness.h" | 43 #include "hydrogen-environment-liveness.h" |
| (...skipping 4248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4291 Handle<JSObject> boilerplate; | 4292 Handle<JSObject> boilerplate; |
| 4292 if (!literals_cell->IsUndefined()) { | 4293 if (!literals_cell->IsUndefined()) { |
| 4293 // Retrieve the boilerplate | 4294 // Retrieve the boilerplate |
| 4294 site = Handle<AllocationSite>::cast(literals_cell); | 4295 site = Handle<AllocationSite>::cast(literals_cell); |
| 4295 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), | 4296 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), |
| 4296 isolate()); | 4297 isolate()); |
| 4297 } | 4298 } |
| 4298 | 4299 |
| 4299 if (!boilerplate.is_null() && | 4300 if (!boilerplate.is_null() && |
| 4300 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { | 4301 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { |
| 4301 literal = BuildFastLiteral(boilerplate); | 4302 AllocationSiteUsageContext usage_context(isolate(), site, false); |
| 4303 usage_context.EnterNewScope(); |
| 4304 literal = BuildFastLiteral(boilerplate, &usage_context); |
| 4305 usage_context.ExitScope(site, boilerplate); |
| 4302 } else { | 4306 } else { |
| 4303 NoObservableSideEffectsScope no_effects(this); | 4307 NoObservableSideEffectsScope no_effects(this); |
| 4304 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 4308 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
| 4305 Handle<FixedArray> constant_properties = expr->constant_properties(); | 4309 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 4306 int literal_index = expr->literal_index(); | 4310 int literal_index = expr->literal_index(); |
| 4307 int flags = expr->fast_elements() | 4311 int flags = expr->fast_elements() |
| 4308 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; | 4312 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; |
| 4309 flags |= expr->has_function() | 4313 flags |= expr->has_function() |
| 4310 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; | 4314 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; |
| 4311 | 4315 |
| 4312 Add<HPushArgument>(Add<HConstant>(closure_literals)); | 4316 Add<HPushArgument>(Add<HConstant>(closure_literals)); |
| 4313 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4317 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 4314 Add<HPushArgument>(Add<HConstant>(constant_properties)); | 4318 Add<HPushArgument>(Add<HConstant>(constant_properties)); |
| 4315 Add<HPushArgument>(Add<HConstant>(flags)); | 4319 Add<HPushArgument>(Add<HConstant>(flags)); |
| 4316 | 4320 |
| 4321 // TODO(mvstanton): Add a flag to turn off creation of any |
| 4322 // AllocationMementos for this call: we are in crankshaft and should have |
| 4323 // learned enough about transition behavior to stop emitting mementos. |
| 4317 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; | 4324 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; |
| 4318 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4325 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 4319 Runtime::FunctionForId(function_id), | 4326 Runtime::FunctionForId(function_id), |
| 4320 4); | 4327 4); |
| 4321 } | 4328 } |
| 4322 | 4329 |
| 4323 // The object is expected in the bailout environment during computation | 4330 // The object is expected in the bailout environment during computation |
| 4324 // of the property values and is the value of the entire expression. | 4331 // of the property values and is the value of the entire expression. |
| 4325 Push(literal); | 4332 Push(literal); |
| 4326 | 4333 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4397 ASSERT(current_block()->HasPredecessor()); | 4404 ASSERT(current_block()->HasPredecessor()); |
| 4398 ZoneList<Expression*>* subexprs = expr->values(); | 4405 ZoneList<Expression*>* subexprs = expr->values(); |
| 4399 int length = subexprs->length(); | 4406 int length = subexprs->length(); |
| 4400 HInstruction* literal; | 4407 HInstruction* literal; |
| 4401 | 4408 |
| 4402 Handle<AllocationSite> site; | 4409 Handle<AllocationSite> site; |
| 4403 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); | 4410 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); |
| 4404 bool uninitialized = false; | 4411 bool uninitialized = false; |
| 4405 Handle<Object> literals_cell(literals->get(expr->literal_index()), | 4412 Handle<Object> literals_cell(literals->get(expr->literal_index()), |
| 4406 isolate()); | 4413 isolate()); |
| 4407 Handle<Object> raw_boilerplate; | 4414 Handle<JSObject> boilerplate_object; |
| 4408 if (literals_cell->IsUndefined()) { | 4415 if (literals_cell->IsUndefined()) { |
| 4409 uninitialized = true; | 4416 uninitialized = true; |
| 4410 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( | 4417 Handle<Object> raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
| 4411 isolate(), literals, expr->constant_elements()); | 4418 isolate(), literals, expr->constant_elements()); |
| 4412 if (raw_boilerplate.is_null()) { | 4419 if (raw_boilerplate.is_null()) { |
| 4413 return Bailout(kArrayBoilerplateCreationFailed); | 4420 return Bailout(kArrayBoilerplateCreationFailed); |
| 4414 } | 4421 } |
| 4415 | 4422 |
| 4416 site = isolate()->factory()->NewAllocationSite(); | 4423 boilerplate_object = Handle<JSObject>::cast(raw_boilerplate); |
| 4417 site->set_transition_info(*raw_boilerplate); | 4424 AllocationSiteCreationContext creation_context(isolate()); |
| 4425 site = creation_context.EnterNewScope(); |
| 4426 if (JSObject::DeepWalk(boilerplate_object, &creation_context).is_null()) { |
| 4427 return Bailout(kArrayBoilerplateCreationFailed); |
| 4428 } |
| 4429 creation_context.ExitScope(site, boilerplate_object); |
| 4418 literals->set(expr->literal_index(), *site); | 4430 literals->set(expr->literal_index(), *site); |
| 4419 | 4431 |
| 4420 if (JSObject::cast(*raw_boilerplate)->elements()->map() == | 4432 if (boilerplate_object->elements()->map() == |
| 4421 isolate()->heap()->fixed_cow_array_map()) { | 4433 isolate()->heap()->fixed_cow_array_map()) { |
| 4422 isolate()->counters()->cow_arrays_created_runtime()->Increment(); | 4434 isolate()->counters()->cow_arrays_created_runtime()->Increment(); |
| 4423 } | 4435 } |
| 4424 } else { | 4436 } else { |
| 4425 ASSERT(literals_cell->IsAllocationSite()); | 4437 ASSERT(literals_cell->IsAllocationSite()); |
| 4426 site = Handle<AllocationSite>::cast(literals_cell); | 4438 site = Handle<AllocationSite>::cast(literals_cell); |
| 4427 raw_boilerplate = Handle<Object>(site->transition_info(), isolate()); | 4439 boilerplate_object = Handle<JSObject>( |
| 4440 JSObject::cast(site->transition_info()), isolate()); |
| 4428 } | 4441 } |
| 4429 | 4442 |
| 4430 ASSERT(!raw_boilerplate.is_null()); | 4443 ASSERT(!boilerplate_object.is_null()); |
| 4431 ASSERT(site->IsLiteralSite()); | 4444 ASSERT(site->SitePointsToLiteral()); |
| 4432 | 4445 |
| 4433 Handle<JSObject> boilerplate_object = | |
| 4434 Handle<JSObject>::cast(raw_boilerplate); | |
| 4435 ElementsKind boilerplate_elements_kind = | 4446 ElementsKind boilerplate_elements_kind = |
| 4436 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind(); | 4447 boilerplate_object->GetElementsKind(); |
| 4437 | |
| 4438 ASSERT(AllocationSite::CanTrack(boilerplate_object->map()->instance_type())); | |
| 4439 | 4448 |
| 4440 // Check whether to use fast or slow deep-copying for boilerplate. | 4449 // Check whether to use fast or slow deep-copying for boilerplate. |
| 4441 int max_properties = kMaxFastLiteralProperties; | 4450 int max_properties = kMaxFastLiteralProperties; |
| 4442 if (IsFastLiteral(boilerplate_object, | 4451 if (IsFastLiteral(boilerplate_object, |
| 4443 kMaxFastLiteralDepth, | 4452 kMaxFastLiteralDepth, |
| 4444 &max_properties)) { | 4453 &max_properties)) { |
| 4445 literal = BuildFastLiteral(boilerplate_object); | 4454 AllocationSiteUsageContext usage_context(isolate(), site, false); |
| 4455 usage_context.EnterNewScope(); |
| 4456 literal = BuildFastLiteral(boilerplate_object, &usage_context); |
| 4457 usage_context.ExitScope(site, boilerplate_object); |
| 4446 } else { | 4458 } else { |
| 4447 NoObservableSideEffectsScope no_effects(this); | 4459 NoObservableSideEffectsScope no_effects(this); |
| 4448 // Boilerplate already exists and constant elements are never accessed, | 4460 // Boilerplate already exists and constant elements are never accessed, |
| 4449 // pass an empty fixed array to the runtime function instead. | 4461 // pass an empty fixed array to the runtime function instead. |
| 4450 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 4462 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
| 4451 int literal_index = expr->literal_index(); | 4463 int literal_index = expr->literal_index(); |
| 4452 | 4464 |
| 4453 Add<HPushArgument>(Add<HConstant>(literals)); | 4465 Add<HPushArgument>(Add<HConstant>(literals)); |
| 4454 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4466 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 4455 Add<HPushArgument>(Add<HConstant>(constants)); | 4467 Add<HPushArgument>(Add<HConstant>(constants)); |
| 4456 | 4468 |
| 4469 // TODO(mvstanton): Consider a flag to turn off creation of any |
| 4470 // AllocationMementos for this call: we are in crankshaft and should have |
| 4471 // learned enough about transition behavior to stop emitting mementos. |
| 4457 Runtime::FunctionId function_id = (expr->depth() > 1) | 4472 Runtime::FunctionId function_id = (expr->depth() > 1) |
| 4458 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; | 4473 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; |
| 4459 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4474 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 4460 Runtime::FunctionForId(function_id), | 4475 Runtime::FunctionForId(function_id), |
| 4461 3); | 4476 3); |
| 4462 | 4477 |
| 4463 // De-opt if elements kind changed from boilerplate_elements_kind. | 4478 // De-opt if elements kind changed from boilerplate_elements_kind. |
| 4464 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); | 4479 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); |
| 4465 literal = Add<HCheckMaps>(literal, map, top_info()); | 4480 literal = Add<HCheckMaps>(literal, map, top_info()); |
| 4466 } | 4481 } |
| (...skipping 3868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8335 if (function_state()->outer() != NULL) { | 8350 if (function_state()->outer() != NULL) { |
| 8336 return New<HConstant>( | 8351 return New<HConstant>( |
| 8337 function_state()->compilation_info()->closure()); | 8352 function_state()->compilation_info()->closure()); |
| 8338 } else { | 8353 } else { |
| 8339 return new(zone()) HThisFunction; | 8354 return new(zone()) HThisFunction; |
| 8340 } | 8355 } |
| 8341 } | 8356 } |
| 8342 | 8357 |
| 8343 | 8358 |
| 8344 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 8359 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
| 8345 Handle<JSObject> boilerplate_object) { | 8360 Handle<JSObject> boilerplate_object, |
| 8361 AllocationSiteContext* site_context) { |
| 8346 NoObservableSideEffectsScope no_effects(this); | 8362 NoObservableSideEffectsScope no_effects(this); |
| 8347 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 8363 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
| 8348 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 8364 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
| 8349 | 8365 |
| 8350 HType type = instance_type == JS_ARRAY_TYPE | 8366 HType type = instance_type == JS_ARRAY_TYPE |
| 8351 ? HType::JSArray() : HType::JSObject(); | 8367 ? HType::JSArray() : HType::JSObject(); |
| 8352 HValue* object_size_constant = Add<HConstant>( | 8368 HValue* object_size_constant = Add<HConstant>( |
| 8353 boilerplate_object->map()->instance_size()); | 8369 boilerplate_object->map()->instance_size()); |
| 8354 HInstruction* object = Add<HAllocate>(object_size_constant, type, | 8370 HInstruction* object = Add<HAllocate>(object_size_constant, type, |
| 8355 isolate()->heap()->GetPretenureMode(), instance_type); | 8371 isolate()->heap()->GetPretenureMode(), instance_type); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8367 if (boilerplate_object->HasFastDoubleElements()) { | 8383 if (boilerplate_object->HasFastDoubleElements()) { |
| 8368 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8384 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 8369 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); | 8385 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); |
| 8370 } else { | 8386 } else { |
| 8371 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8387 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 8372 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); | 8388 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); |
| 8373 } | 8389 } |
| 8374 } | 8390 } |
| 8375 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); | 8391 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); |
| 8376 | 8392 |
| 8377 | |
| 8378 // Copy object elements if non-COW. | 8393 // Copy object elements if non-COW. |
| 8379 if (object_elements != NULL) { | 8394 if (object_elements != NULL) { |
| 8380 BuildEmitElements(boilerplate_object, elements, object_elements); | 8395 BuildEmitElements(boilerplate_object, elements, object_elements, |
| 8396 site_context); |
| 8381 } | 8397 } |
| 8382 | 8398 |
| 8383 // Copy in-object properties. | 8399 // Copy in-object properties. |
| 8384 if (boilerplate_object->map()->NumberOfFields() != 0) { | 8400 if (boilerplate_object->map()->NumberOfFields() != 0) { |
| 8385 BuildEmitInObjectProperties(boilerplate_object, object); | 8401 BuildEmitInObjectProperties(boilerplate_object, object, site_context); |
| 8386 } | 8402 } |
| 8387 return object; | 8403 return object; |
| 8388 } | 8404 } |
| 8389 | 8405 |
| 8390 | 8406 |
| 8391 void HOptimizedGraphBuilder::BuildEmitObjectHeader( | 8407 void HOptimizedGraphBuilder::BuildEmitObjectHeader( |
| 8392 Handle<JSObject> boilerplate_object, | 8408 Handle<JSObject> boilerplate_object, |
| 8393 HInstruction* object) { | 8409 HInstruction* object) { |
| 8394 ASSERT(boilerplate_object->properties()->length() == 0); | 8410 ASSERT(boilerplate_object->properties()->length() == 0); |
| 8395 | 8411 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8427 Handle<Object>(boilerplate_object->elements(), isolate()); | 8443 Handle<Object>(boilerplate_object->elements(), isolate()); |
| 8428 object_elements = Add<HConstant>(elements_field); | 8444 object_elements = Add<HConstant>(elements_field); |
| 8429 } | 8445 } |
| 8430 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 8446 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 8431 object_elements); | 8447 object_elements); |
| 8432 } | 8448 } |
| 8433 | 8449 |
| 8434 | 8450 |
| 8435 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 8451 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
| 8436 Handle<JSObject> boilerplate_object, | 8452 Handle<JSObject> boilerplate_object, |
| 8437 HInstruction* object) { | 8453 HInstruction* object, |
| 8454 AllocationSiteContext* site_context) { |
| 8438 Handle<DescriptorArray> descriptors( | 8455 Handle<DescriptorArray> descriptors( |
| 8439 boilerplate_object->map()->instance_descriptors()); | 8456 boilerplate_object->map()->instance_descriptors()); |
| 8440 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); | 8457 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 8441 | 8458 |
| 8442 int copied_fields = 0; | 8459 int copied_fields = 0; |
| 8443 for (int i = 0; i < limit; i++) { | 8460 for (int i = 0; i < limit; i++) { |
| 8444 PropertyDetails details = descriptors->GetDetails(i); | 8461 PropertyDetails details = descriptors->GetDetails(i); |
| 8445 if (details.type() != FIELD) continue; | 8462 if (details.type() != FIELD) continue; |
| 8446 copied_fields++; | 8463 copied_fields++; |
| 8447 int index = descriptors->GetFieldIndex(i); | 8464 int index = descriptors->GetFieldIndex(i); |
| 8448 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 8465 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
| 8449 Handle<Name> name(descriptors->GetKey(i)); | 8466 Handle<Name> name(descriptors->GetKey(i)); |
| 8450 Handle<Object> value = | 8467 Handle<Object> value = |
| 8451 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 8468 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
| 8452 isolate()); | 8469 isolate()); |
| 8453 | 8470 |
| 8454 // The access for the store depends on the type of the boilerplate. | 8471 // The access for the store depends on the type of the boilerplate. |
| 8455 HObjectAccess access = boilerplate_object->IsJSArray() ? | 8472 HObjectAccess access = boilerplate_object->IsJSArray() ? |
| 8456 HObjectAccess::ForJSArrayOffset(property_offset) : | 8473 HObjectAccess::ForJSArrayOffset(property_offset) : |
| 8457 HObjectAccess::ForJSObjectOffset(property_offset); | 8474 HObjectAccess::ForJSObjectOffset(property_offset); |
| 8458 | 8475 |
| 8459 if (value->IsJSObject()) { | 8476 if (value->IsJSObject()) { |
| 8460 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8477 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 8461 HInstruction* result = BuildFastLiteral(value_object); | 8478 Handle<AllocationSite> current_site = site_context->EnterNewScope(); |
| 8479 HInstruction* result = |
| 8480 BuildFastLiteral(value_object, site_context); |
| 8481 site_context->ExitScope(current_site, value_object); |
| 8462 Add<HStoreNamedField>(object, access, result); | 8482 Add<HStoreNamedField>(object, access, result); |
| 8463 } else { | 8483 } else { |
| 8464 Representation representation = details.representation(); | 8484 Representation representation = details.representation(); |
| 8465 HInstruction* value_instruction = Add<HConstant>(value); | 8485 HInstruction* value_instruction = Add<HConstant>(value); |
| 8466 | 8486 |
| 8467 if (representation.IsDouble()) { | 8487 if (representation.IsDouble()) { |
| 8468 // Allocate a HeapNumber box and store the value into it. | 8488 // Allocate a HeapNumber box and store the value into it. |
| 8469 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); | 8489 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); |
| 8490 // TODO(mvstanton): This heap number alloc does not have a corresponding |
| 8491 // AllocationSite. That is okay because |
| 8492 // 1) it's a child object of another object with a valid allocation site |
| 8493 // 2) we can just use the mode of the parent object for pretenuring |
| 8494 // The todo is replace GetPretenureMode() with |
| 8495 // site_context->top()->GetPretenureMode(). |
| 8470 HInstruction* double_box = | 8496 HInstruction* double_box = |
| 8471 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), | 8497 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), |
| 8472 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); | 8498 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); |
| 8473 AddStoreMapConstant(double_box, | 8499 AddStoreMapConstant(double_box, |
| 8474 isolate()->factory()->heap_number_map()); | 8500 isolate()->factory()->heap_number_map()); |
| 8475 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), | 8501 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), |
| 8476 value_instruction); | 8502 value_instruction); |
| 8477 value_instruction = double_box; | 8503 value_instruction = double_box; |
| 8478 } | 8504 } |
| 8479 | 8505 |
| 8480 Add<HStoreNamedField>(object, access, value_instruction); | 8506 Add<HStoreNamedField>(object, access, value_instruction); |
| 8481 } | 8507 } |
| 8482 } | 8508 } |
| 8483 | 8509 |
| 8484 int inobject_properties = boilerplate_object->map()->inobject_properties(); | 8510 int inobject_properties = boilerplate_object->map()->inobject_properties(); |
| 8485 HInstruction* value_instruction = | 8511 HInstruction* value_instruction = |
| 8486 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); | 8512 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); |
| 8487 for (int i = copied_fields; i < inobject_properties; i++) { | 8513 for (int i = copied_fields; i < inobject_properties; i++) { |
| 8488 ASSERT(boilerplate_object->IsJSObject()); | 8514 ASSERT(boilerplate_object->IsJSObject()); |
| 8489 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); | 8515 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); |
| 8490 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); | 8516 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); |
| 8491 Add<HStoreNamedField>(object, access, value_instruction); | 8517 Add<HStoreNamedField>(object, access, value_instruction); |
| 8492 } | 8518 } |
| 8493 } | 8519 } |
| 8494 | 8520 |
| 8495 | 8521 |
| 8496 void HOptimizedGraphBuilder::BuildEmitElements( | 8522 void HOptimizedGraphBuilder::BuildEmitElements( |
| 8497 Handle<JSObject> boilerplate_object, | 8523 Handle<JSObject> boilerplate_object, |
| 8498 Handle<FixedArrayBase> elements, | 8524 Handle<FixedArrayBase> elements, |
| 8499 HValue* object_elements) { | 8525 HValue* object_elements, |
| 8526 AllocationSiteContext* site_context) { |
| 8500 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 8527 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
| 8501 int elements_length = elements->length(); | 8528 int elements_length = elements->length(); |
| 8502 HValue* object_elements_length = Add<HConstant>(elements_length); | 8529 HValue* object_elements_length = Add<HConstant>(elements_length); |
| 8503 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); | 8530 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); |
| 8504 | 8531 |
| 8505 // Copy elements backing store content. | 8532 // Copy elements backing store content. |
| 8506 if (elements->IsFixedDoubleArray()) { | 8533 if (elements->IsFixedDoubleArray()) { |
| 8507 BuildEmitFixedDoubleArray(elements, kind, object_elements); | 8534 BuildEmitFixedDoubleArray(elements, kind, object_elements); |
| 8508 } else if (elements->IsFixedArray()) { | 8535 } else if (elements->IsFixedArray()) { |
| 8509 BuildEmitFixedArray(elements, kind, object_elements); | 8536 BuildEmitFixedArray(elements, kind, object_elements, |
| 8537 site_context); |
| 8510 } else { | 8538 } else { |
| 8511 UNREACHABLE(); | 8539 UNREACHABLE(); |
| 8512 } | 8540 } |
| 8513 } | 8541 } |
| 8514 | 8542 |
| 8515 | 8543 |
| 8516 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 8544 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
| 8517 Handle<FixedArrayBase> elements, | 8545 Handle<FixedArrayBase> elements, |
| 8518 ElementsKind kind, | 8546 ElementsKind kind, |
| 8519 HValue* object_elements) { | 8547 HValue* object_elements) { |
| 8520 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8548 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 8521 int elements_length = elements->length(); | 8549 int elements_length = elements->length(); |
| 8522 for (int i = 0; i < elements_length; i++) { | 8550 for (int i = 0; i < elements_length; i++) { |
| 8523 HValue* key_constant = Add<HConstant>(i); | 8551 HValue* key_constant = Add<HConstant>(i); |
| 8524 HInstruction* value_instruction = | 8552 HInstruction* value_instruction = |
| 8525 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8553 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 8526 static_cast<HValue*>(NULL), kind, | 8554 static_cast<HValue*>(NULL), kind, |
| 8527 ALLOW_RETURN_HOLE); | 8555 ALLOW_RETURN_HOLE); |
| 8528 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, | 8556 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 8529 value_instruction, kind); | 8557 value_instruction, kind); |
| 8530 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 8558 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 8531 } | 8559 } |
| 8532 } | 8560 } |
| 8533 | 8561 |
| 8534 | 8562 |
| 8535 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 8563 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 8536 Handle<FixedArrayBase> elements, | 8564 Handle<FixedArrayBase> elements, |
| 8537 ElementsKind kind, | 8565 ElementsKind kind, |
| 8538 HValue* object_elements) { | 8566 HValue* object_elements, |
| 8567 AllocationSiteContext* site_context) { |
| 8539 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8568 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 8540 int elements_length = elements->length(); | 8569 int elements_length = elements->length(); |
| 8541 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 8570 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 8542 for (int i = 0; i < elements_length; i++) { | 8571 for (int i = 0; i < elements_length; i++) { |
| 8543 Handle<Object> value(fast_elements->get(i), isolate()); | 8572 Handle<Object> value(fast_elements->get(i), isolate()); |
| 8544 HValue* key_constant = Add<HConstant>(i); | 8573 HValue* key_constant = Add<HConstant>(i); |
| 8545 if (value->IsJSObject()) { | 8574 if (value->IsJSObject()) { |
| 8546 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8575 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 8547 HInstruction* result = BuildFastLiteral(value_object); | 8576 Handle<AllocationSite> current_site = site_context->EnterNewScope(); |
| 8577 HInstruction* result = |
| 8578 BuildFastLiteral(value_object, site_context); |
| 8579 site_context->ExitScope(current_site, value_object); |
| 8548 Add<HStoreKeyed>(object_elements, key_constant, result, kind); | 8580 Add<HStoreKeyed>(object_elements, key_constant, result, kind); |
| 8549 } else { | 8581 } else { |
| 8550 HInstruction* value_instruction = | 8582 HInstruction* value_instruction = |
| 8551 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8583 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 8552 static_cast<HValue*>(NULL), kind, | 8584 static_cast<HValue*>(NULL), kind, |
| 8553 ALLOW_RETURN_HOLE); | 8585 ALLOW_RETURN_HOLE); |
| 8554 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); | 8586 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
| 8555 } | 8587 } |
| 8556 } | 8588 } |
| 8557 } | 8589 } |
| (...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9809 if (ShouldProduceTraceOutput()) { | 9841 if (ShouldProduceTraceOutput()) { |
| 9810 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9842 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9811 } | 9843 } |
| 9812 | 9844 |
| 9813 #ifdef DEBUG | 9845 #ifdef DEBUG |
| 9814 graph_->Verify(false); // No full verify. | 9846 graph_->Verify(false); // No full verify. |
| 9815 #endif | 9847 #endif |
| 9816 } | 9848 } |
| 9817 | 9849 |
| 9818 } } // namespace v8::internal | 9850 } } // namespace v8::internal |
| OLD | NEW |