| 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 4303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4346 Handle<JSObject> boilerplate; | 4347 Handle<JSObject> boilerplate; |
| 4347 if (!literals_cell->IsUndefined()) { | 4348 if (!literals_cell->IsUndefined()) { |
| 4348 // Retrieve the boilerplate | 4349 // Retrieve the boilerplate |
| 4349 site = Handle<AllocationSite>::cast(literals_cell); | 4350 site = Handle<AllocationSite>::cast(literals_cell); |
| 4350 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), | 4351 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), |
| 4351 isolate()); | 4352 isolate()); |
| 4352 } | 4353 } |
| 4353 | 4354 |
| 4354 if (!boilerplate.is_null() && | 4355 if (!boilerplate.is_null() && |
| 4355 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { | 4356 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { |
| 4356 literal = BuildFastLiteral(boilerplate); | 4357 AllocationSiteUsageContext usage_context(isolate(), site, false); |
| 4358 usage_context.EnterNewScope(); |
| 4359 literal = BuildFastLiteral(boilerplate, &usage_context); |
| 4360 usage_context.ExitScope(site, boilerplate); |
| 4357 } else { | 4361 } else { |
| 4358 NoObservableSideEffectsScope no_effects(this); | 4362 NoObservableSideEffectsScope no_effects(this); |
| 4359 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 4363 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
| 4360 Handle<FixedArray> constant_properties = expr->constant_properties(); | 4364 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 4361 int literal_index = expr->literal_index(); | 4365 int literal_index = expr->literal_index(); |
| 4362 int flags = expr->fast_elements() | 4366 int flags = expr->fast_elements() |
| 4363 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; | 4367 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; |
| 4364 flags |= expr->has_function() | 4368 flags |= expr->has_function() |
| 4365 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; | 4369 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; |
| 4366 | 4370 |
| 4367 Add<HPushArgument>(Add<HConstant>(closure_literals)); | 4371 Add<HPushArgument>(Add<HConstant>(closure_literals)); |
| 4368 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4372 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 4369 Add<HPushArgument>(Add<HConstant>(constant_properties)); | 4373 Add<HPushArgument>(Add<HConstant>(constant_properties)); |
| 4370 Add<HPushArgument>(Add<HConstant>(flags)); | 4374 Add<HPushArgument>(Add<HConstant>(flags)); |
| 4371 | 4375 |
| 4376 // TODO(mvstanton): Add a flag to turn off creation of any |
| 4377 // AllocationMementos for this call: we are in crankshaft and should have |
| 4378 // learned enough about transition behavior to stop emitting mementos. |
| 4372 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; | 4379 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; |
| 4373 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4380 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 4374 Runtime::FunctionForId(function_id), | 4381 Runtime::FunctionForId(function_id), |
| 4375 4); | 4382 4); |
| 4376 } | 4383 } |
| 4377 | 4384 |
| 4378 // The object is expected in the bailout environment during computation | 4385 // The object is expected in the bailout environment during computation |
| 4379 // of the property values and is the value of the entire expression. | 4386 // of the property values and is the value of the entire expression. |
| 4380 Push(literal); | 4387 Push(literal); |
| 4381 | 4388 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4452 ASSERT(current_block()->HasPredecessor()); | 4459 ASSERT(current_block()->HasPredecessor()); |
| 4453 ZoneList<Expression*>* subexprs = expr->values(); | 4460 ZoneList<Expression*>* subexprs = expr->values(); |
| 4454 int length = subexprs->length(); | 4461 int length = subexprs->length(); |
| 4455 HInstruction* literal; | 4462 HInstruction* literal; |
| 4456 | 4463 |
| 4457 Handle<AllocationSite> site; | 4464 Handle<AllocationSite> site; |
| 4458 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); | 4465 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); |
| 4459 bool uninitialized = false; | 4466 bool uninitialized = false; |
| 4460 Handle<Object> literals_cell(literals->get(expr->literal_index()), | 4467 Handle<Object> literals_cell(literals->get(expr->literal_index()), |
| 4461 isolate()); | 4468 isolate()); |
| 4462 Handle<Object> raw_boilerplate; | 4469 Handle<JSObject> boilerplate_object; |
| 4463 if (literals_cell->IsUndefined()) { | 4470 if (literals_cell->IsUndefined()) { |
| 4464 uninitialized = true; | 4471 uninitialized = true; |
| 4465 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( | 4472 Handle<Object> raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
| 4466 isolate(), literals, expr->constant_elements()); | 4473 isolate(), literals, expr->constant_elements()); |
| 4467 if (raw_boilerplate.is_null()) { | 4474 if (raw_boilerplate.is_null()) { |
| 4468 return Bailout(kArrayBoilerplateCreationFailed); | 4475 return Bailout(kArrayBoilerplateCreationFailed); |
| 4469 } | 4476 } |
| 4470 | 4477 |
| 4471 site = isolate()->factory()->NewAllocationSite(); | 4478 boilerplate_object = Handle<JSObject>::cast(raw_boilerplate); |
| 4472 site->set_transition_info(*raw_boilerplate); | 4479 AllocationSiteCreationContext creation_context(isolate()); |
| 4480 site = creation_context.EnterNewScope(); |
| 4481 JSObject::DeepWalk(boilerplate_object, &creation_context); |
| 4482 creation_context.ExitScope(site, boilerplate_object); |
| 4473 literals->set(expr->literal_index(), *site); | 4483 literals->set(expr->literal_index(), *site); |
| 4474 | 4484 |
| 4475 if (JSObject::cast(*raw_boilerplate)->elements()->map() == | 4485 if (boilerplate_object->elements()->map() == |
| 4476 isolate()->heap()->fixed_cow_array_map()) { | 4486 isolate()->heap()->fixed_cow_array_map()) { |
| 4477 isolate()->counters()->cow_arrays_created_runtime()->Increment(); | 4487 isolate()->counters()->cow_arrays_created_runtime()->Increment(); |
| 4478 } | 4488 } |
| 4479 } else { | 4489 } else { |
| 4480 ASSERT(literals_cell->IsAllocationSite()); | 4490 ASSERT(literals_cell->IsAllocationSite()); |
| 4481 site = Handle<AllocationSite>::cast(literals_cell); | 4491 site = Handle<AllocationSite>::cast(literals_cell); |
| 4482 raw_boilerplate = Handle<Object>(site->transition_info(), isolate()); | 4492 boilerplate_object = Handle<JSObject>( |
| 4493 JSObject::cast(site->transition_info()), isolate()); |
| 4483 } | 4494 } |
| 4484 | 4495 |
| 4485 ASSERT(!raw_boilerplate.is_null()); | 4496 ASSERT(!boilerplate_object.is_null()); |
| 4486 ASSERT(site->IsLiteralSite()); | 4497 ASSERT(site->SitePointsToLiteral()); |
| 4487 | 4498 |
| 4488 Handle<JSObject> boilerplate_object = | |
| 4489 Handle<JSObject>::cast(raw_boilerplate); | |
| 4490 ElementsKind boilerplate_elements_kind = | 4499 ElementsKind boilerplate_elements_kind = |
| 4491 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind(); | 4500 boilerplate_object->GetElementsKind(); |
| 4492 | |
| 4493 ASSERT(AllocationSite::CanTrack(boilerplate_object->map()->instance_type())); | |
| 4494 | 4501 |
| 4495 // Check whether to use fast or slow deep-copying for boilerplate. | 4502 // Check whether to use fast or slow deep-copying for boilerplate. |
| 4496 int max_properties = kMaxFastLiteralProperties; | 4503 int max_properties = kMaxFastLiteralProperties; |
| 4497 if (IsFastLiteral(boilerplate_object, | 4504 if (IsFastLiteral(boilerplate_object, |
| 4498 kMaxFastLiteralDepth, | 4505 kMaxFastLiteralDepth, |
| 4499 &max_properties)) { | 4506 &max_properties)) { |
| 4500 literal = BuildFastLiteral(boilerplate_object); | 4507 AllocationSiteUsageContext usage_context(isolate(), site, false); |
| 4508 usage_context.EnterNewScope(); |
| 4509 literal = BuildFastLiteral(boilerplate_object, &usage_context); |
| 4510 usage_context.ExitScope(site, boilerplate_object); |
| 4501 } else { | 4511 } else { |
| 4502 NoObservableSideEffectsScope no_effects(this); | 4512 NoObservableSideEffectsScope no_effects(this); |
| 4503 // Boilerplate already exists and constant elements are never accessed, | 4513 // Boilerplate already exists and constant elements are never accessed, |
| 4504 // pass an empty fixed array to the runtime function instead. | 4514 // pass an empty fixed array to the runtime function instead. |
| 4505 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 4515 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
| 4506 int literal_index = expr->literal_index(); | 4516 int literal_index = expr->literal_index(); |
| 4507 | 4517 |
| 4508 Add<HPushArgument>(Add<HConstant>(literals)); | 4518 Add<HPushArgument>(Add<HConstant>(literals)); |
| 4509 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4519 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 4510 Add<HPushArgument>(Add<HConstant>(constants)); | 4520 Add<HPushArgument>(Add<HConstant>(constants)); |
| 4511 | 4521 |
| 4522 // TODO(mvstanton): Consider a flag to turn off creation of any |
| 4523 // AllocationMementos for this call: we are in crankshaft and should have |
| 4524 // learned enough about transition behavior to stop emitting mementos. |
| 4512 Runtime::FunctionId function_id = (expr->depth() > 1) | 4525 Runtime::FunctionId function_id = (expr->depth() > 1) |
| 4513 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; | 4526 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; |
| 4514 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4527 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 4515 Runtime::FunctionForId(function_id), | 4528 Runtime::FunctionForId(function_id), |
| 4516 3); | 4529 3); |
| 4517 | 4530 |
| 4518 // De-opt if elements kind changed from boilerplate_elements_kind. | 4531 // De-opt if elements kind changed from boilerplate_elements_kind. |
| 4519 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); | 4532 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); |
| 4520 literal = Add<HCheckMaps>(literal, map, top_info()); | 4533 literal = Add<HCheckMaps>(literal, map, top_info()); |
| 4521 } | 4534 } |
| (...skipping 3871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8393 if (function_state()->outer() != NULL) { | 8406 if (function_state()->outer() != NULL) { |
| 8394 return New<HConstant>( | 8407 return New<HConstant>( |
| 8395 function_state()->compilation_info()->closure()); | 8408 function_state()->compilation_info()->closure()); |
| 8396 } else { | 8409 } else { |
| 8397 return new(zone()) HThisFunction; | 8410 return new(zone()) HThisFunction; |
| 8398 } | 8411 } |
| 8399 } | 8412 } |
| 8400 | 8413 |
| 8401 | 8414 |
| 8402 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 8415 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
| 8403 Handle<JSObject> boilerplate_object) { | 8416 Handle<JSObject> boilerplate_object, |
| 8417 AllocationSiteContext* site_context) { |
| 8404 NoObservableSideEffectsScope no_effects(this); | 8418 NoObservableSideEffectsScope no_effects(this); |
| 8405 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 8419 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
| 8406 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 8420 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
| 8407 | 8421 |
| 8408 HType type = instance_type == JS_ARRAY_TYPE | 8422 HType type = instance_type == JS_ARRAY_TYPE |
| 8409 ? HType::JSArray() : HType::JSObject(); | 8423 ? HType::JSArray() : HType::JSObject(); |
| 8410 HValue* object_size_constant = Add<HConstant>( | 8424 HValue* object_size_constant = Add<HConstant>( |
| 8411 boilerplate_object->map()->instance_size()); | 8425 boilerplate_object->map()->instance_size()); |
| 8412 HInstruction* object = Add<HAllocate>(object_size_constant, type, | 8426 HInstruction* object = Add<HAllocate>(object_size_constant, type, |
| 8413 isolate()->heap()->GetPretenureMode(), instance_type); | 8427 isolate()->heap()->GetPretenureMode(), instance_type); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8425 if (boilerplate_object->HasFastDoubleElements()) { | 8439 if (boilerplate_object->HasFastDoubleElements()) { |
| 8426 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8440 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 8427 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); | 8441 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); |
| 8428 } else { | 8442 } else { |
| 8429 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8443 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 8430 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); | 8444 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); |
| 8431 } | 8445 } |
| 8432 } | 8446 } |
| 8433 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); | 8447 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); |
| 8434 | 8448 |
| 8435 | |
| 8436 // Copy object elements if non-COW. | 8449 // Copy object elements if non-COW. |
| 8437 if (object_elements != NULL) { | 8450 if (object_elements != NULL) { |
| 8438 BuildEmitElements(boilerplate_object, elements, object_elements); | 8451 BuildEmitElements(boilerplate_object, elements, object_elements, |
| 8452 site_context); |
| 8439 } | 8453 } |
| 8440 | 8454 |
| 8441 // Copy in-object properties. | 8455 // Copy in-object properties. |
| 8442 if (boilerplate_object->map()->NumberOfFields() != 0) { | 8456 if (boilerplate_object->map()->NumberOfFields() != 0) { |
| 8443 BuildEmitInObjectProperties(boilerplate_object, object); | 8457 BuildEmitInObjectProperties(boilerplate_object, object, site_context); |
| 8444 } | 8458 } |
| 8445 return object; | 8459 return object; |
| 8446 } | 8460 } |
| 8447 | 8461 |
| 8448 | 8462 |
| 8449 void HOptimizedGraphBuilder::BuildEmitObjectHeader( | 8463 void HOptimizedGraphBuilder::BuildEmitObjectHeader( |
| 8450 Handle<JSObject> boilerplate_object, | 8464 Handle<JSObject> boilerplate_object, |
| 8451 HInstruction* object) { | 8465 HInstruction* object) { |
| 8452 ASSERT(boilerplate_object->properties()->length() == 0); | 8466 ASSERT(boilerplate_object->properties()->length() == 0); |
| 8453 | 8467 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8485 Handle<Object>(boilerplate_object->elements(), isolate()); | 8499 Handle<Object>(boilerplate_object->elements(), isolate()); |
| 8486 object_elements = Add<HConstant>(elements_field); | 8500 object_elements = Add<HConstant>(elements_field); |
| 8487 } | 8501 } |
| 8488 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 8502 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 8489 object_elements); | 8503 object_elements); |
| 8490 } | 8504 } |
| 8491 | 8505 |
| 8492 | 8506 |
| 8493 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 8507 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
| 8494 Handle<JSObject> boilerplate_object, | 8508 Handle<JSObject> boilerplate_object, |
| 8495 HInstruction* object) { | 8509 HInstruction* object, |
| 8510 AllocationSiteContext* site_context) { |
| 8496 Handle<DescriptorArray> descriptors( | 8511 Handle<DescriptorArray> descriptors( |
| 8497 boilerplate_object->map()->instance_descriptors()); | 8512 boilerplate_object->map()->instance_descriptors()); |
| 8498 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); | 8513 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 8499 | 8514 |
| 8500 int copied_fields = 0; | 8515 int copied_fields = 0; |
| 8501 for (int i = 0; i < limit; i++) { | 8516 for (int i = 0; i < limit; i++) { |
| 8502 PropertyDetails details = descriptors->GetDetails(i); | 8517 PropertyDetails details = descriptors->GetDetails(i); |
| 8503 if (details.type() != FIELD) continue; | 8518 if (details.type() != FIELD) continue; |
| 8504 copied_fields++; | 8519 copied_fields++; |
| 8505 int index = descriptors->GetFieldIndex(i); | 8520 int index = descriptors->GetFieldIndex(i); |
| 8506 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 8521 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
| 8507 Handle<Name> name(descriptors->GetKey(i)); | 8522 Handle<Name> name(descriptors->GetKey(i)); |
| 8508 Handle<Object> value = | 8523 Handle<Object> value = |
| 8509 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 8524 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
| 8510 isolate()); | 8525 isolate()); |
| 8511 | 8526 |
| 8512 // The access for the store depends on the type of the boilerplate. | 8527 // The access for the store depends on the type of the boilerplate. |
| 8513 HObjectAccess access = boilerplate_object->IsJSArray() ? | 8528 HObjectAccess access = boilerplate_object->IsJSArray() ? |
| 8514 HObjectAccess::ForJSArrayOffset(property_offset) : | 8529 HObjectAccess::ForJSArrayOffset(property_offset) : |
| 8515 HObjectAccess::ForJSObjectOffset(property_offset); | 8530 HObjectAccess::ForJSObjectOffset(property_offset); |
| 8516 | 8531 |
| 8517 if (value->IsJSObject()) { | 8532 if (value->IsJSObject()) { |
| 8518 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8533 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 8519 HInstruction* result = BuildFastLiteral(value_object); | 8534 Handle<AllocationSite> current_site = site_context->EnterNewScope(); |
| 8535 HInstruction* result = |
| 8536 BuildFastLiteral(value_object, site_context); |
| 8537 site_context->ExitScope(current_site, value_object); |
| 8520 Add<HStoreNamedField>(object, access, result); | 8538 Add<HStoreNamedField>(object, access, result); |
| 8521 } else { | 8539 } else { |
| 8522 Representation representation = details.representation(); | 8540 Representation representation = details.representation(); |
| 8523 HInstruction* value_instruction = Add<HConstant>(value); | 8541 HInstruction* value_instruction = Add<HConstant>(value); |
| 8524 | 8542 |
| 8525 if (representation.IsDouble()) { | 8543 if (representation.IsDouble()) { |
| 8526 // Allocate a HeapNumber box and store the value into it. | 8544 // Allocate a HeapNumber box and store the value into it. |
| 8527 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); | 8545 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); |
| 8546 // TODO(mvstanton): This heap number alloc does not have a corresponding |
| 8547 // AllocationSite. That is okay because |
| 8548 // 1) it's a child object of another object with a valid allocation site |
| 8549 // 2) we can just use the mode of the parent object for pretenuring |
| 8550 // The todo is replace GetPretenureMode() with |
| 8551 // site_context->top()->GetPretenureMode(). |
| 8528 HInstruction* double_box = | 8552 HInstruction* double_box = |
| 8529 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), | 8553 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), |
| 8530 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); | 8554 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); |
| 8531 AddStoreMapConstant(double_box, | 8555 AddStoreMapConstant(double_box, |
| 8532 isolate()->factory()->heap_number_map()); | 8556 isolate()->factory()->heap_number_map()); |
| 8533 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), | 8557 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), |
| 8534 value_instruction); | 8558 value_instruction); |
| 8535 value_instruction = double_box; | 8559 value_instruction = double_box; |
| 8536 } | 8560 } |
| 8537 | 8561 |
| 8538 Add<HStoreNamedField>(object, access, value_instruction); | 8562 Add<HStoreNamedField>(object, access, value_instruction); |
| 8539 } | 8563 } |
| 8540 } | 8564 } |
| 8541 | 8565 |
| 8542 int inobject_properties = boilerplate_object->map()->inobject_properties(); | 8566 int inobject_properties = boilerplate_object->map()->inobject_properties(); |
| 8543 HInstruction* value_instruction = | 8567 HInstruction* value_instruction = |
| 8544 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); | 8568 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); |
| 8545 for (int i = copied_fields; i < inobject_properties; i++) { | 8569 for (int i = copied_fields; i < inobject_properties; i++) { |
| 8546 ASSERT(boilerplate_object->IsJSObject()); | 8570 ASSERT(boilerplate_object->IsJSObject()); |
| 8547 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); | 8571 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); |
| 8548 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); | 8572 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); |
| 8549 Add<HStoreNamedField>(object, access, value_instruction); | 8573 Add<HStoreNamedField>(object, access, value_instruction); |
| 8550 } | 8574 } |
| 8551 } | 8575 } |
| 8552 | 8576 |
| 8553 | 8577 |
| 8554 void HOptimizedGraphBuilder::BuildEmitElements( | 8578 void HOptimizedGraphBuilder::BuildEmitElements( |
| 8555 Handle<JSObject> boilerplate_object, | 8579 Handle<JSObject> boilerplate_object, |
| 8556 Handle<FixedArrayBase> elements, | 8580 Handle<FixedArrayBase> elements, |
| 8557 HValue* object_elements) { | 8581 HValue* object_elements, |
| 8582 AllocationSiteContext* site_context) { |
| 8558 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 8583 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
| 8559 int elements_length = elements->length(); | 8584 int elements_length = elements->length(); |
| 8560 HValue* object_elements_length = Add<HConstant>(elements_length); | 8585 HValue* object_elements_length = Add<HConstant>(elements_length); |
| 8561 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); | 8586 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); |
| 8562 | 8587 |
| 8563 // Copy elements backing store content. | 8588 // Copy elements backing store content. |
| 8564 if (elements->IsFixedDoubleArray()) { | 8589 if (elements->IsFixedDoubleArray()) { |
| 8565 BuildEmitFixedDoubleArray(elements, kind, object_elements); | 8590 BuildEmitFixedDoubleArray(elements, kind, object_elements); |
| 8566 } else if (elements->IsFixedArray()) { | 8591 } else if (elements->IsFixedArray()) { |
| 8567 BuildEmitFixedArray(elements, kind, object_elements); | 8592 BuildEmitFixedArray(elements, kind, object_elements, |
| 8593 site_context); |
| 8568 } else { | 8594 } else { |
| 8569 UNREACHABLE(); | 8595 UNREACHABLE(); |
| 8570 } | 8596 } |
| 8571 } | 8597 } |
| 8572 | 8598 |
| 8573 | 8599 |
| 8574 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 8600 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
| 8575 Handle<FixedArrayBase> elements, | 8601 Handle<FixedArrayBase> elements, |
| 8576 ElementsKind kind, | 8602 ElementsKind kind, |
| 8577 HValue* object_elements) { | 8603 HValue* object_elements) { |
| 8578 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8604 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 8579 int elements_length = elements->length(); | 8605 int elements_length = elements->length(); |
| 8580 for (int i = 0; i < elements_length; i++) { | 8606 for (int i = 0; i < elements_length; i++) { |
| 8581 HValue* key_constant = Add<HConstant>(i); | 8607 HValue* key_constant = Add<HConstant>(i); |
| 8582 HInstruction* value_instruction = | 8608 HInstruction* value_instruction = |
| 8583 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8609 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 8584 static_cast<HValue*>(NULL), kind, | 8610 static_cast<HValue*>(NULL), kind, |
| 8585 ALLOW_RETURN_HOLE); | 8611 ALLOW_RETURN_HOLE); |
| 8586 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, | 8612 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 8587 value_instruction, kind); | 8613 value_instruction, kind); |
| 8588 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 8614 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 8589 } | 8615 } |
| 8590 } | 8616 } |
| 8591 | 8617 |
| 8592 | 8618 |
| 8593 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 8619 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 8594 Handle<FixedArrayBase> elements, | 8620 Handle<FixedArrayBase> elements, |
| 8595 ElementsKind kind, | 8621 ElementsKind kind, |
| 8596 HValue* object_elements) { | 8622 HValue* object_elements, |
| 8623 AllocationSiteContext* site_context) { |
| 8597 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8624 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 8598 int elements_length = elements->length(); | 8625 int elements_length = elements->length(); |
| 8599 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 8626 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 8600 for (int i = 0; i < elements_length; i++) { | 8627 for (int i = 0; i < elements_length; i++) { |
| 8601 Handle<Object> value(fast_elements->get(i), isolate()); | 8628 Handle<Object> value(fast_elements->get(i), isolate()); |
| 8602 HValue* key_constant = Add<HConstant>(i); | 8629 HValue* key_constant = Add<HConstant>(i); |
| 8603 if (value->IsJSObject()) { | 8630 if (value->IsJSObject()) { |
| 8604 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8631 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 8605 HInstruction* result = BuildFastLiteral(value_object); | 8632 Handle<AllocationSite> current_site = site_context->EnterNewScope(); |
| 8633 HInstruction* result = |
| 8634 BuildFastLiteral(value_object, site_context); |
| 8635 site_context->ExitScope(current_site, value_object); |
| 8606 Add<HStoreKeyed>(object_elements, key_constant, result, kind); | 8636 Add<HStoreKeyed>(object_elements, key_constant, result, kind); |
| 8607 } else { | 8637 } else { |
| 8608 HInstruction* value_instruction = | 8638 HInstruction* value_instruction = |
| 8609 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8639 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 8610 static_cast<HValue*>(NULL), kind, | 8640 static_cast<HValue*>(NULL), kind, |
| 8611 ALLOW_RETURN_HOLE); | 8641 ALLOW_RETURN_HOLE); |
| 8612 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); | 8642 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
| 8613 } | 8643 } |
| 8614 } | 8644 } |
| 8615 } | 8645 } |
| (...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9867 if (ShouldProduceTraceOutput()) { | 9897 if (ShouldProduceTraceOutput()) { |
| 9868 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9898 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9869 } | 9899 } |
| 9870 | 9900 |
| 9871 #ifdef DEBUG | 9901 #ifdef DEBUG |
| 9872 graph_->Verify(false); // No full verify. | 9902 graph_->Verify(false); // No full verify. |
| 9873 #endif | 9903 #endif |
| 9874 } | 9904 } |
| 9875 | 9905 |
| 9876 } } // namespace v8::internal | 9906 } } // namespace v8::internal |
| OLD | NEW |