Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 | 982 |
| 983 | 983 |
| 984 void HGraphBuilder::AddSimulate(BailoutId id, | 984 void HGraphBuilder::AddSimulate(BailoutId id, |
| 985 RemovableSimulate removable) { | 985 RemovableSimulate removable) { |
| 986 ASSERT(current_block() != NULL); | 986 ASSERT(current_block() != NULL); |
| 987 ASSERT(no_side_effects_scope_count_ == 0); | 987 ASSERT(no_side_effects_scope_count_ == 0); |
| 988 current_block()->AddSimulate(id, removable); | 988 current_block()->AddSimulate(id, removable); |
| 989 } | 989 } |
| 990 | 990 |
| 991 | 991 |
| 992 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length) { | |
| 993 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length); | |
| 994 AddInstruction(result); | |
| 995 return result; | |
| 996 } | |
| 997 | |
| 998 | |
| 999 HReturn* HGraphBuilder::AddReturn(HValue* value) { | 992 HReturn* HGraphBuilder::AddReturn(HValue* value) { |
| 1000 HValue* context = environment()->LookupContext(); | 993 HValue* context = environment()->LookupContext(); |
| 1001 int num_parameters = graph()->info()->num_parameters(); | 994 int num_parameters = graph()->info()->num_parameters(); |
| 1002 HValue* params = AddInstruction(new(graph()->zone()) | 995 HValue* params = AddInstruction(new(graph()->zone()) |
| 1003 HConstant(num_parameters)); | 996 HConstant(num_parameters)); |
| 1004 HReturn* return_instruction = new(graph()->zone()) | 997 HReturn* return_instruction = new(graph()->zone()) |
| 1005 HReturn(value, context, params); | 998 HReturn(value, context, params); |
| 1006 current_block()->FinishExit(return_instruction); | 999 current_block()->FinishExit(return_instruction); |
| 1007 return return_instruction; | 1000 return return_instruction; |
| 1008 } | 1001 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1168 new_length->ClearFlag(HValue::kCanOverflow); | 1161 new_length->ClearFlag(HValue::kCanOverflow); |
| 1169 | 1162 |
| 1170 Representation representation = IsFastElementsKind(kind) | 1163 Representation representation = IsFastElementsKind(kind) |
| 1171 ? Representation::Smi() : Representation::Tagged(); | 1164 ? Representation::Smi() : Representation::Tagged(); |
| 1172 AddStore(object, HObjectAccess::ForArrayLength(), new_length, | 1165 AddStore(object, HObjectAccess::ForArrayLength(), new_length, |
| 1173 representation); | 1166 representation); |
| 1174 } | 1167 } |
| 1175 | 1168 |
| 1176 length_checker.Else(); | 1169 length_checker.Else(); |
| 1177 | 1170 |
| 1178 AddBoundsCheck(key, length); | 1171 Add<HBoundsCheck>(key, length); |
| 1179 environment()->Push(elements); | 1172 environment()->Push(elements); |
| 1180 | 1173 |
| 1181 length_checker.End(); | 1174 length_checker.End(); |
| 1182 | 1175 |
| 1183 return environment()->Pop(); | 1176 return environment()->Pop(); |
| 1184 } | 1177 } |
| 1185 | 1178 |
| 1186 | 1179 |
| 1187 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1180 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
| 1188 HValue* elements, | 1181 HValue* elements, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1273 negative_checker.Then(); | 1266 negative_checker.Then(); |
| 1274 HInstruction* result = BuildExternalArrayElementAccess( | 1267 HInstruction* result = BuildExternalArrayElementAccess( |
| 1275 external_elements, key, val, bounds_check, | 1268 external_elements, key, val, bounds_check, |
| 1276 elements_kind, is_store); | 1269 elements_kind, is_store); |
| 1277 AddInstruction(result); | 1270 AddInstruction(result); |
| 1278 negative_checker.ElseDeopt(); | 1271 negative_checker.ElseDeopt(); |
| 1279 length_checker.End(); | 1272 length_checker.End(); |
| 1280 return result; | 1273 return result; |
| 1281 } else { | 1274 } else { |
| 1282 ASSERT(store_mode == STANDARD_STORE); | 1275 ASSERT(store_mode == STANDARD_STORE); |
| 1283 checked_key = AddBoundsCheck(key, length); | 1276 checked_key = Add<HBoundsCheck>(key, length); |
| 1284 HLoadExternalArrayPointer* external_elements = | 1277 HLoadExternalArrayPointer* external_elements = |
| 1285 new(zone) HLoadExternalArrayPointer(elements); | 1278 new(zone) HLoadExternalArrayPointer(elements); |
| 1286 AddInstruction(external_elements); | 1279 AddInstruction(external_elements); |
| 1287 return AddInstruction(BuildExternalArrayElementAccess( | 1280 return AddInstruction(BuildExternalArrayElementAccess( |
| 1288 external_elements, checked_key, val, mapcheck, | 1281 external_elements, checked_key, val, mapcheck, |
| 1289 elements_kind, is_store)); | 1282 elements_kind, is_store)); |
| 1290 } | 1283 } |
| 1291 } | 1284 } |
| 1292 ASSERT(fast_smi_only_elements || | 1285 ASSERT(fast_smi_only_elements || |
| 1293 fast_elements || | 1286 fast_elements || |
| 1294 IsFastDoubleElementsKind(elements_kind)); | 1287 IsFastDoubleElementsKind(elements_kind)); |
| 1295 | 1288 |
| 1296 // In case val is stored into a fast smi array, assure that the value is a smi | 1289 // In case val is stored into a fast smi array, assure that the value is a smi |
| 1297 // before manipulating the backing store. Otherwise the actual store may | 1290 // before manipulating the backing store. Otherwise the actual store may |
| 1298 // deopt, leaving the backing store in an invalid state. | 1291 // deopt, leaving the backing store in an invalid state. |
| 1299 if (is_store && IsFastSmiElementsKind(elements_kind) && | 1292 if (is_store && IsFastSmiElementsKind(elements_kind) && |
| 1300 !val->type().IsSmi()) { | 1293 !val->type().IsSmi()) { |
| 1301 val = AddInstruction(new(zone) HForceRepresentation( | 1294 val = AddInstruction(new(zone) HForceRepresentation( |
| 1302 val, Representation::Smi())); | 1295 val, Representation::Smi())); |
| 1303 } | 1296 } |
| 1304 | 1297 |
| 1305 if (IsGrowStoreMode(store_mode)) { | 1298 if (IsGrowStoreMode(store_mode)) { |
| 1306 NoObservableSideEffectsScope no_effects(this); | 1299 NoObservableSideEffectsScope no_effects(this); |
| 1307 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, | 1300 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, |
| 1308 length, key, is_js_array); | 1301 length, key, is_js_array); |
| 1309 checked_key = key; | 1302 checked_key = key; |
| 1310 } else { | 1303 } else { |
| 1311 checked_key = AddBoundsCheck(key, length); | 1304 checked_key = Add<HBoundsCheck>(key, length); |
| 1312 | 1305 |
| 1313 if (is_store && (fast_elements || fast_smi_only_elements)) { | 1306 if (is_store && (fast_elements || fast_smi_only_elements)) { |
| 1314 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { | 1307 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { |
| 1315 NoObservableSideEffectsScope no_effects(this); | 1308 NoObservableSideEffectsScope no_effects(this); |
| 1316 | 1309 |
| 1317 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, | 1310 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, |
| 1318 length); | 1311 length); |
| 1319 } else { | 1312 } else { |
| 1320 HCheckMaps* check_cow_map = HCheckMaps::New( | 1313 HCheckMaps* check_cow_map = HCheckMaps::New( |
| 1321 elements, isolate()->factory()->fixed_array_map(), zone); | 1314 elements, isolate()->factory()->fixed_array_map(), zone); |
| (...skipping 3328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4650 } | 4643 } |
| 4651 } | 4644 } |
| 4652 | 4645 |
| 4653 | 4646 |
| 4654 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 4647 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
| 4655 Push(instr); | 4648 Push(instr); |
| 4656 AddInstruction(instr); | 4649 AddInstruction(instr); |
| 4657 } | 4650 } |
| 4658 | 4651 |
| 4659 | 4652 |
| 4660 void HOptimizedGraphBuilder::AddSoftDeoptimize() { | 4653 void HOptimizedGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) { |
| 4661 isolate()->counters()->soft_deopts_requested()->Increment(); | 4654 isolate()->counters()->soft_deopts_requested()->Increment(); |
| 4662 if (FLAG_always_opt) return; | 4655 if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return; |
| 4663 if (current_block()->IsDeoptimizing()) return; | 4656 if (current_block()->IsDeoptimizing()) return; |
| 4664 AddInstruction(new(zone()) HSoftDeoptimize()); | 4657 AddInstruction(new(zone()) HSoftDeoptimize()); |
| 4665 isolate()->counters()->soft_deopts_inserted()->Increment(); | 4658 isolate()->counters()->soft_deopts_inserted()->Increment(); |
| 4666 current_block()->MarkAsDeoptimizing(); | 4659 current_block()->MarkAsDeoptimizing(); |
| 4667 graph()->set_has_soft_deoptimize(true); | 4660 graph()->set_has_soft_deoptimize(true); |
| 4668 } | 4661 } |
| 4669 | 4662 |
| 4670 | 4663 |
| 4671 template <class Instruction> | 4664 template <class Instruction> |
| 4672 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 4665 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
| (...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5620 LookupGlobalProperty(variable, &lookup, false); | 5613 LookupGlobalProperty(variable, &lookup, false); |
| 5621 | 5614 |
| 5622 if (type == kUseCell && | 5615 if (type == kUseCell && |
| 5623 current_info()->global_object()->IsAccessCheckNeeded()) { | 5616 current_info()->global_object()->IsAccessCheckNeeded()) { |
| 5624 type = kUseGeneric; | 5617 type = kUseGeneric; |
| 5625 } | 5618 } |
| 5626 | 5619 |
| 5627 if (type == kUseCell) { | 5620 if (type == kUseCell) { |
| 5628 Handle<GlobalObject> global(current_info()->global_object()); | 5621 Handle<GlobalObject> global(current_info()->global_object()); |
| 5629 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 5622 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 5630 HLoadGlobalCell* instr = | 5623 if (cell->type()->IsConstant()) { |
| 5631 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); | 5624 cell->AddDependentCompilationInfo(top_info()); |
| 5632 return ast_context()->ReturnInstruction(instr, expr->id()); | 5625 HConstant* constant = |
| 5626 new(zone()) HConstant(cell->type()->AsConstant()); | |
| 5627 return ast_context()->ReturnInstruction(constant, expr->id()); | |
| 5628 } else { | |
| 5629 HLoadGlobalCell* instr = | |
| 5630 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); | |
| 5631 return ast_context()->ReturnInstruction(instr, expr->id()); | |
| 5632 } | |
| 5633 } else { | 5633 } else { |
| 5634 HValue* context = environment()->LookupContext(); | 5634 HValue* context = environment()->LookupContext(); |
| 5635 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 5635 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 5636 AddInstruction(global_object); | 5636 AddInstruction(global_object); |
| 5637 HLoadGlobalGeneric* instr = | 5637 HLoadGlobalGeneric* instr = |
| 5638 new(zone()) HLoadGlobalGeneric(context, | 5638 new(zone()) HLoadGlobalGeneric(context, |
| 5639 global_object, | 5639 global_object, |
| 5640 variable->name(), | 5640 variable->name(), |
| 5641 ast_context()->is_for_typeof()); | 5641 ast_context()->is_for_typeof()); |
| 5642 instr->set_position(expr->position()); | 5642 instr->set_position(expr->position()); |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6545 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6545 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
| 6546 Variable* var, | 6546 Variable* var, |
| 6547 HValue* value, | 6547 HValue* value, |
| 6548 int position, | 6548 int position, |
| 6549 BailoutId ast_id) { | 6549 BailoutId ast_id) { |
| 6550 LookupResult lookup(isolate()); | 6550 LookupResult lookup(isolate()); |
| 6551 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6551 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
| 6552 if (type == kUseCell) { | 6552 if (type == kUseCell) { |
| 6553 Handle<GlobalObject> global(current_info()->global_object()); | 6553 Handle<GlobalObject> global(current_info()->global_object()); |
| 6554 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 6554 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 6555 if (cell->type()->IsConstant()) { | |
| 6556 IfBuilder builder(this); | |
| 6557 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); | |
| 6558 builder.If<HCompareObjectEqAndBranch>(value, constant); | |
| 6559 builder.Then(); | |
| 6560 builder.Else(); | |
| 6561 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); | |
|
rossberg
2013/06/25 10:47:38
I'm a bit at a loss why this flag is needed.
danno
2013/06/28 13:56:05
Most soft deopts are only for performance. Without
| |
| 6562 builder.End(); | |
| 6563 } | |
| 6555 HInstruction* instr = | 6564 HInstruction* instr = |
| 6556 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6565 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
| 6557 instr->set_position(position); | 6566 instr->set_position(position); |
| 6558 AddInstruction(instr); | 6567 AddInstruction(instr); |
| 6559 if (instr->HasObservableSideEffects()) { | 6568 if (instr->HasObservableSideEffects()) { |
| 6560 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6569 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
| 6561 } | 6570 } |
| 6562 } else { | 6571 } else { |
| 6563 HValue* context = environment()->LookupContext(); | 6572 HValue* context = environment()->LookupContext(); |
| 6564 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6573 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7283 elements_kind <= LAST_ELEMENTS_KIND; | 7292 elements_kind <= LAST_ELEMENTS_KIND; |
| 7284 elements_kind = ElementsKind(elements_kind + 1)) { | 7293 elements_kind = ElementsKind(elements_kind + 1)) { |
| 7285 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some | 7294 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some |
| 7286 // code that's executed for all external array cases. | 7295 // code that's executed for all external array cases. |
| 7287 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == | 7296 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == |
| 7288 LAST_ELEMENTS_KIND); | 7297 LAST_ELEMENTS_KIND); |
| 7289 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND | 7298 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
| 7290 && todo_external_array) { | 7299 && todo_external_array) { |
| 7291 HInstruction* length = | 7300 HInstruction* length = |
| 7292 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 7301 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 7293 checked_key = AddBoundsCheck(key, length); | 7302 checked_key = Add<HBoundsCheck>(key, length); |
| 7294 external_elements = new(zone()) HLoadExternalArrayPointer(elements); | 7303 external_elements = new(zone()) HLoadExternalArrayPointer(elements); |
| 7295 AddInstruction(external_elements); | 7304 AddInstruction(external_elements); |
| 7296 } | 7305 } |
| 7297 if (type_todo[elements_kind]) { | 7306 if (type_todo[elements_kind]) { |
| 7298 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7307 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 7299 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7308 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 7300 HCompareConstantEqAndBranch* elements_kind_branch = | 7309 HCompareConstantEqAndBranch* elements_kind_branch = |
| 7301 new(zone()) HCompareConstantEqAndBranch( | 7310 new(zone()) HCompareConstantEqAndBranch( |
| 7302 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 7311 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
| 7303 elements_kind_branch->SetSuccessorAt(0, if_true); | 7312 elements_kind_branch->SetSuccessorAt(0, if_true); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 7326 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 7335 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
| 7327 typecheck->SetSuccessorAt(0, if_jsarray); | 7336 typecheck->SetSuccessorAt(0, if_jsarray); |
| 7328 typecheck->SetSuccessorAt(1, if_fastobject); | 7337 typecheck->SetSuccessorAt(1, if_fastobject); |
| 7329 current_block()->Finish(typecheck); | 7338 current_block()->Finish(typecheck); |
| 7330 | 7339 |
| 7331 set_current_block(if_jsarray); | 7340 set_current_block(if_jsarray); |
| 7332 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), | 7341 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), |
| 7333 typecheck, Representation::Smi()); | 7342 typecheck, Representation::Smi()); |
| 7334 length->set_type(HType::Smi()); | 7343 length->set_type(HType::Smi()); |
| 7335 | 7344 |
| 7336 checked_key = AddBoundsCheck(key, length); | 7345 checked_key = Add<HBoundsCheck>(key, length); |
| 7337 access = AddInstruction(BuildFastElementAccess( | 7346 access = AddInstruction(BuildFastElementAccess( |
| 7338 elements, checked_key, val, elements_kind_branch, | 7347 elements, checked_key, val, elements_kind_branch, |
| 7339 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7348 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
| 7340 if (!is_store) { | 7349 if (!is_store) { |
| 7341 Push(access); | 7350 Push(access); |
| 7342 } | 7351 } |
| 7343 | 7352 |
| 7344 *has_side_effects |= access->HasObservableSideEffects(); | 7353 *has_side_effects |= access->HasObservableSideEffects(); |
| 7345 // The caller will use has_side_effects and add correct Simulate. | 7354 // The caller will use has_side_effects and add correct Simulate. |
| 7346 access->SetFlag(HValue::kHasNoObservableSideEffects); | 7355 access->SetFlag(HValue::kHasNoObservableSideEffects); |
| 7347 if (position != -1) { | 7356 if (position != -1) { |
| 7348 access->set_position(position); | 7357 access->set_position(position); |
| 7349 } | 7358 } |
| 7350 if_jsarray->GotoNoSimulate(join); | 7359 if_jsarray->GotoNoSimulate(join); |
| 7351 | 7360 |
| 7352 set_current_block(if_fastobject); | 7361 set_current_block(if_fastobject); |
| 7353 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 7362 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 7354 checked_key = AddBoundsCheck(key, length); | 7363 checked_key = Add<HBoundsCheck>(key, length); |
| 7355 access = AddInstruction(BuildFastElementAccess( | 7364 access = AddInstruction(BuildFastElementAccess( |
| 7356 elements, checked_key, val, elements_kind_branch, | 7365 elements, checked_key, val, elements_kind_branch, |
| 7357 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7366 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
| 7358 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 7367 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
| 7359 if (is_store) { | 7368 if (is_store) { |
| 7360 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 7369 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
| 7361 } else { | 7370 } else { |
| 7362 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 7371 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
| 7363 } | 7372 } |
| 7364 } else { // External array elements. | 7373 } else { // External array elements. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7496 Push(graph()->GetArgumentsObject()); | 7505 Push(graph()->GetArgumentsObject()); |
| 7497 VisitForValue(expr->key()); | 7506 VisitForValue(expr->key()); |
| 7498 if (HasStackOverflow() || current_block() == NULL) return true; | 7507 if (HasStackOverflow() || current_block() == NULL) return true; |
| 7499 HValue* key = Pop(); | 7508 HValue* key = Pop(); |
| 7500 Drop(1); // Arguments object. | 7509 Drop(1); // Arguments object. |
| 7501 if (function_state()->outer() == NULL) { | 7510 if (function_state()->outer() == NULL) { |
| 7502 HInstruction* elements = AddInstruction( | 7511 HInstruction* elements = AddInstruction( |
| 7503 new(zone()) HArgumentsElements(false)); | 7512 new(zone()) HArgumentsElements(false)); |
| 7504 HInstruction* length = AddInstruction( | 7513 HInstruction* length = AddInstruction( |
| 7505 new(zone()) HArgumentsLength(elements)); | 7514 new(zone()) HArgumentsLength(elements)); |
| 7506 HInstruction* checked_key = AddBoundsCheck(key, length); | 7515 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 7507 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7516 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| 7508 } else { | 7517 } else { |
| 7509 EnsureArgumentsArePushedForAccess(); | 7518 EnsureArgumentsArePushedForAccess(); |
| 7510 | 7519 |
| 7511 // Number of arguments without receiver. | 7520 // Number of arguments without receiver. |
| 7512 HInstruction* elements = function_state()->arguments_elements(); | 7521 HInstruction* elements = function_state()->arguments_elements(); |
| 7513 int argument_count = environment()-> | 7522 int argument_count = environment()-> |
| 7514 arguments_environment()->parameter_count() - 1; | 7523 arguments_environment()->parameter_count() - 1; |
| 7515 HInstruction* length = AddInstruction(new(zone()) HConstant( | 7524 HInstruction* length = AddInstruction(new(zone()) HConstant( |
| 7516 argument_count)); | 7525 argument_count)); |
| 7517 HInstruction* checked_key = AddBoundsCheck(key, length); | 7526 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 7518 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7527 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| 7519 } | 7528 } |
| 7520 } | 7529 } |
| 7521 ast_context()->ReturnInstruction(result, expr->id()); | 7530 ast_context()->ReturnInstruction(result, expr->id()); |
| 7522 return true; | 7531 return true; |
| 7523 } | 7532 } |
| 7524 | 7533 |
| 7525 | 7534 |
| 7526 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7535 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
| 7527 ASSERT(!HasStackOverflow()); | 7536 ASSERT(!HasStackOverflow()); |
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8886 expr->target().is_identical_to(array_function); | 8895 expr->target().is_identical_to(array_function); |
| 8887 | 8896 |
| 8888 CHECK_ALIVE(VisitArgument(expr->expression())); | 8897 CHECK_ALIVE(VisitArgument(expr->expression())); |
| 8889 HValue* constructor = HPushArgument::cast(Top())->argument(); | 8898 HValue* constructor = HPushArgument::cast(Top())->argument(); |
| 8890 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8899 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 8891 HCallNew* call; | 8900 HCallNew* call; |
| 8892 if (use_call_new_array) { | 8901 if (use_call_new_array) { |
| 8893 Handle<Cell> cell = expr->allocation_info_cell(); | 8902 Handle<Cell> cell = expr->allocation_info_cell(); |
| 8894 AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); | 8903 AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); |
| 8895 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 8904 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
| 8896 cell); | 8905 cell, expr->elements_kind()); |
| 8897 } else { | 8906 } else { |
| 8898 call = new(zone()) HCallNew(context, constructor, argument_count); | 8907 call = new(zone()) HCallNew(context, constructor, argument_count); |
| 8899 } | 8908 } |
| 8900 Drop(argument_count); | 8909 Drop(argument_count); |
| 8901 call->set_position(expr->position()); | 8910 call->set_position(expr->position()); |
| 8902 return ast_context()->ReturnInstruction(call, expr->id()); | 8911 return ast_context()->ReturnInstruction(call, expr->id()); |
| 8903 } | 8912 } |
| 8904 } | 8913 } |
| 8905 | 8914 |
| 8906 | 8915 |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9336 if (i < 0 || i >= s->length()) { | 9345 if (i < 0 || i >= s->length()) { |
| 9337 return new(zone()) HConstant(OS::nan_value()); | 9346 return new(zone()) HConstant(OS::nan_value()); |
| 9338 } | 9347 } |
| 9339 return new(zone()) HConstant(s->Get(i)); | 9348 return new(zone()) HConstant(s->Get(i)); |
| 9340 } | 9349 } |
| 9341 } | 9350 } |
| 9342 BuildCheckNonSmi(string); | 9351 BuildCheckNonSmi(string); |
| 9343 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 9352 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 9344 HInstruction* length = HStringLength::New(zone(), string); | 9353 HInstruction* length = HStringLength::New(zone(), string); |
| 9345 AddInstruction(length); | 9354 AddInstruction(length); |
| 9346 HInstruction* checked_index = AddBoundsCheck(index, length); | 9355 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
| 9347 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 9356 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 9348 } | 9357 } |
| 9349 | 9358 |
| 9350 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 9359 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
| 9351 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 9360 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
| 9352 HValue* const32_minus_sa) { | 9361 HValue* const32_minus_sa) { |
| 9353 if (!const32_minus_sa->IsSub()) return false; | 9362 if (!const32_minus_sa->IsSub()) return false; |
| 9354 HSub* sub = HSub::cast(const32_minus_sa); | 9363 HSub* sub = HSub::cast(const32_minus_sa); |
| 9355 if (sa != sub->right()) return false; | 9364 if (sa != sub->right()) return false; |
| 9356 HValue* const32 = sub->left(); | 9365 HValue* const32 = sub->left(); |
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9991 | 10000 |
| 9992 // Copy object elements if non-COW. | 10001 // Copy object elements if non-COW. |
| 9993 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, | 10002 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, |
| 9994 object_offset, elements_offset, elements_size); | 10003 object_offset, elements_offset, elements_size); |
| 9995 if (object_elements != NULL) { | 10004 if (object_elements != NULL) { |
| 9996 BuildEmitElements(elements, original_elements, kind, object_elements, | 10005 BuildEmitElements(elements, original_elements, kind, object_elements, |
| 9997 target, offset); | 10006 target, offset); |
| 9998 } | 10007 } |
| 9999 | 10008 |
| 10000 // Copy in-object properties. | 10009 // Copy in-object properties. |
| 10001 HValue* object_properties = | 10010 Handle<DescriptorArray> descriptors( |
| 10002 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 10011 boilerplate_object->map()->instance_descriptors()); |
| 10003 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, | 10012 int descriptor_count = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 10004 object_properties, target, offset); | 10013 bool has_field = false; |
| 10014 for (int i = 0; i < descriptor_count; i++) { | |
| 10015 PropertyDetails details = descriptors->GetDetails(i); | |
| 10016 if (details.type() != FIELD) continue; | |
| 10017 has_field = true; | |
| 10018 } | |
| 10019 | |
| 10020 if (has_field) { | |
| 10021 HValue* object_properties = | |
| 10022 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | |
| 10023 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, | |
| 10024 object_properties, target, offset); | |
| 10025 } | |
| 10005 | 10026 |
| 10006 // Create allocation site info. | 10027 // Create allocation site info. |
| 10007 if (mode == TRACK_ALLOCATION_SITE && | 10028 if (mode == TRACK_ALLOCATION_SITE && |
| 10008 boilerplate_object->map()->CanTrackAllocationSite()) { | 10029 boilerplate_object->map()->CanTrackAllocationSite()) { |
| 10009 elements_offset += AllocationSiteInfo::kSize; | 10030 elements_offset += AllocationSiteInfo::kSize; |
| 10010 *offset += AllocationSiteInfo::kSize; | 10031 *offset += AllocationSiteInfo::kSize; |
| 10011 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( | 10032 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( |
| 10012 original_boilerplate_object)); | 10033 original_boilerplate_object)); |
| 10013 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 10034 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
| 10014 } | 10035 } |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10503 // Our implementation of arguments (based on this stack frame or an | 10524 // Our implementation of arguments (based on this stack frame or an |
| 10504 // adapter below it) does not work for inlined functions. This runtime | 10525 // adapter below it) does not work for inlined functions. This runtime |
| 10505 // function is blacklisted by AstNode::IsInlineable. | 10526 // function is blacklisted by AstNode::IsInlineable. |
| 10506 ASSERT(function_state()->outer() == NULL); | 10527 ASSERT(function_state()->outer() == NULL); |
| 10507 ASSERT(call->arguments()->length() == 1); | 10528 ASSERT(call->arguments()->length() == 1); |
| 10508 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 10529 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 10509 HValue* index = Pop(); | 10530 HValue* index = Pop(); |
| 10510 HInstruction* elements = AddInstruction( | 10531 HInstruction* elements = AddInstruction( |
| 10511 new(zone()) HArgumentsElements(false)); | 10532 new(zone()) HArgumentsElements(false)); |
| 10512 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); | 10533 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); |
| 10513 HInstruction* checked_index = AddBoundsCheck(index, length); | 10534 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
| 10514 HAccessArgumentsAt* result = | 10535 HAccessArgumentsAt* result = |
| 10515 new(zone()) HAccessArgumentsAt(elements, length, checked_index); | 10536 new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
| 10516 return ast_context()->ReturnInstruction(result, call->id()); | 10537 return ast_context()->ReturnInstruction(result, call->id()); |
| 10517 } | 10538 } |
| 10518 | 10539 |
| 10519 | 10540 |
| 10520 // Support for accessing the class and value fields of an object. | 10541 // Support for accessing the class and value fields of an object. |
| 10521 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { | 10542 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
| 10522 // The special form detected by IsClassOfTest is detected before we get here | 10543 // The special form detected by IsClassOfTest is detected before we get here |
| 10523 // and does not cause a bailout. | 10544 // and does not cause a bailout. |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11571 } | 11592 } |
| 11572 } | 11593 } |
| 11573 | 11594 |
| 11574 #ifdef DEBUG | 11595 #ifdef DEBUG |
| 11575 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11596 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11576 if (allocator_ != NULL) allocator_->Verify(); | 11597 if (allocator_ != NULL) allocator_->Verify(); |
| 11577 #endif | 11598 #endif |
| 11578 } | 11599 } |
| 11579 | 11600 |
| 11580 } } // namespace v8::internal | 11601 } } // namespace v8::internal |
| OLD | NEW |