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 3334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4656 current_block()->AddPhi(instr); | 4649 current_block()->AddPhi(instr); |
4657 } | 4650 } |
4658 | 4651 |
4659 | 4652 |
4660 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 4653 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
4661 Push(instr); | 4654 Push(instr); |
4662 AddInstruction(instr); | 4655 AddInstruction(instr); |
4663 } | 4656 } |
4664 | 4657 |
4665 | 4658 |
4666 void HOptimizedGraphBuilder::AddSoftDeoptimize() { | 4659 void HOptimizedGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) { |
4667 isolate()->counters()->soft_deopts_requested()->Increment(); | 4660 isolate()->counters()->soft_deopts_requested()->Increment(); |
4668 if (FLAG_always_opt) return; | 4661 if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return; |
4669 if (current_block()->IsDeoptimizing()) return; | 4662 if (current_block()->IsDeoptimizing()) return; |
4670 AddInstruction(new(zone()) HSoftDeoptimize()); | 4663 AddInstruction(new(zone()) HSoftDeoptimize()); |
4671 isolate()->counters()->soft_deopts_inserted()->Increment(); | 4664 isolate()->counters()->soft_deopts_inserted()->Increment(); |
4672 current_block()->MarkAsDeoptimizing(); | 4665 current_block()->MarkAsDeoptimizing(); |
4673 graph()->set_has_soft_deoptimize(true); | 4666 graph()->set_has_soft_deoptimize(true); |
4674 } | 4667 } |
4675 | 4668 |
4676 | 4669 |
4677 template <class Instruction> | 4670 template <class Instruction> |
4678 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 4671 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5626 LookupGlobalProperty(variable, &lookup, false); | 5619 LookupGlobalProperty(variable, &lookup, false); |
5627 | 5620 |
5628 if (type == kUseCell && | 5621 if (type == kUseCell && |
5629 current_info()->global_object()->IsAccessCheckNeeded()) { | 5622 current_info()->global_object()->IsAccessCheckNeeded()) { |
5630 type = kUseGeneric; | 5623 type = kUseGeneric; |
5631 } | 5624 } |
5632 | 5625 |
5633 if (type == kUseCell) { | 5626 if (type == kUseCell) { |
5634 Handle<GlobalObject> global(current_info()->global_object()); | 5627 Handle<GlobalObject> global(current_info()->global_object()); |
5635 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 5628 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
5636 HLoadGlobalCell* instr = | 5629 if (cell->type()->IsConstant()) { |
5637 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); | 5630 cell->AddDependentCompilationInfo(top_info()); |
5638 return ast_context()->ReturnInstruction(instr, expr->id()); | 5631 HConstant* constant = |
| 5632 new(zone()) HConstant(cell->type()->AsConstant()); |
| 5633 return ast_context()->ReturnInstruction(constant, expr->id()); |
| 5634 } else { |
| 5635 HLoadGlobalCell* instr = |
| 5636 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); |
| 5637 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5638 } |
5639 } else { | 5639 } else { |
5640 HValue* context = environment()->LookupContext(); | 5640 HValue* context = environment()->LookupContext(); |
5641 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 5641 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
5642 AddInstruction(global_object); | 5642 AddInstruction(global_object); |
5643 HLoadGlobalGeneric* instr = | 5643 HLoadGlobalGeneric* instr = |
5644 new(zone()) HLoadGlobalGeneric(context, | 5644 new(zone()) HLoadGlobalGeneric(context, |
5645 global_object, | 5645 global_object, |
5646 variable->name(), | 5646 variable->name(), |
5647 ast_context()->is_for_typeof()); | 5647 ast_context()->is_for_typeof()); |
5648 instr->set_position(expr->position()); | 5648 instr->set_position(expr->position()); |
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6551 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6551 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
6552 Variable* var, | 6552 Variable* var, |
6553 HValue* value, | 6553 HValue* value, |
6554 int position, | 6554 int position, |
6555 BailoutId ast_id) { | 6555 BailoutId ast_id) { |
6556 LookupResult lookup(isolate()); | 6556 LookupResult lookup(isolate()); |
6557 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6557 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
6558 if (type == kUseCell) { | 6558 if (type == kUseCell) { |
6559 Handle<GlobalObject> global(current_info()->global_object()); | 6559 Handle<GlobalObject> global(current_info()->global_object()); |
6560 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 6560 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 6561 if (cell->type()->IsConstant()) { |
| 6562 IfBuilder builder(this); |
| 6563 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); |
| 6564 builder.If<HCompareObjectEqAndBranch>(value, constant); |
| 6565 builder.Then(); |
| 6566 builder.Else(); |
| 6567 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); |
| 6568 builder.End(); |
| 6569 } |
6561 HInstruction* instr = | 6570 HInstruction* instr = |
6562 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6571 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
6563 instr->set_position(position); | 6572 instr->set_position(position); |
6564 AddInstruction(instr); | 6573 AddInstruction(instr); |
6565 if (instr->HasObservableSideEffects()) { | 6574 if (instr->HasObservableSideEffects()) { |
6566 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6575 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
6567 } | 6576 } |
6568 } else { | 6577 } else { |
6569 HValue* context = environment()->LookupContext(); | 6578 HValue* context = environment()->LookupContext(); |
6570 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6579 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7289 elements_kind <= LAST_ELEMENTS_KIND; | 7298 elements_kind <= LAST_ELEMENTS_KIND; |
7290 elements_kind = ElementsKind(elements_kind + 1)) { | 7299 elements_kind = ElementsKind(elements_kind + 1)) { |
7291 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some | 7300 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some |
7292 // code that's executed for all external array cases. | 7301 // code that's executed for all external array cases. |
7293 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == | 7302 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == |
7294 LAST_ELEMENTS_KIND); | 7303 LAST_ELEMENTS_KIND); |
7295 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND | 7304 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
7296 && todo_external_array) { | 7305 && todo_external_array) { |
7297 HInstruction* length = | 7306 HInstruction* length = |
7298 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 7307 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
7299 checked_key = AddBoundsCheck(key, length); | 7308 checked_key = Add<HBoundsCheck>(key, length); |
7300 external_elements = new(zone()) HLoadExternalArrayPointer(elements); | 7309 external_elements = new(zone()) HLoadExternalArrayPointer(elements); |
7301 AddInstruction(external_elements); | 7310 AddInstruction(external_elements); |
7302 } | 7311 } |
7303 if (type_todo[elements_kind]) { | 7312 if (type_todo[elements_kind]) { |
7304 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7313 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
7305 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7314 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
7306 HCompareConstantEqAndBranch* elements_kind_branch = | 7315 HCompareConstantEqAndBranch* elements_kind_branch = |
7307 new(zone()) HCompareConstantEqAndBranch( | 7316 new(zone()) HCompareConstantEqAndBranch( |
7308 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 7317 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
7309 elements_kind_branch->SetSuccessorAt(0, if_true); | 7318 elements_kind_branch->SetSuccessorAt(0, if_true); |
(...skipping 22 matching lines...) Expand all Loading... |
7332 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 7341 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
7333 typecheck->SetSuccessorAt(0, if_jsarray); | 7342 typecheck->SetSuccessorAt(0, if_jsarray); |
7334 typecheck->SetSuccessorAt(1, if_fastobject); | 7343 typecheck->SetSuccessorAt(1, if_fastobject); |
7335 current_block()->Finish(typecheck); | 7344 current_block()->Finish(typecheck); |
7336 | 7345 |
7337 set_current_block(if_jsarray); | 7346 set_current_block(if_jsarray); |
7338 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), | 7347 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), |
7339 typecheck, Representation::Smi()); | 7348 typecheck, Representation::Smi()); |
7340 length->set_type(HType::Smi()); | 7349 length->set_type(HType::Smi()); |
7341 | 7350 |
7342 checked_key = AddBoundsCheck(key, length); | 7351 checked_key = Add<HBoundsCheck>(key, length); |
7343 access = AddInstruction(BuildFastElementAccess( | 7352 access = AddInstruction(BuildFastElementAccess( |
7344 elements, checked_key, val, elements_kind_branch, | 7353 elements, checked_key, val, elements_kind_branch, |
7345 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7354 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
7346 if (!is_store) { | 7355 if (!is_store) { |
7347 Push(access); | 7356 Push(access); |
7348 } | 7357 } |
7349 | 7358 |
7350 *has_side_effects |= access->HasObservableSideEffects(); | 7359 *has_side_effects |= access->HasObservableSideEffects(); |
7351 // The caller will use has_side_effects and add correct Simulate. | 7360 // The caller will use has_side_effects and add correct Simulate. |
7352 access->SetFlag(HValue::kHasNoObservableSideEffects); | 7361 access->SetFlag(HValue::kHasNoObservableSideEffects); |
7353 if (position != -1) { | 7362 if (position != -1) { |
7354 access->set_position(position); | 7363 access->set_position(position); |
7355 } | 7364 } |
7356 if_jsarray->GotoNoSimulate(join); | 7365 if_jsarray->GotoNoSimulate(join); |
7357 | 7366 |
7358 set_current_block(if_fastobject); | 7367 set_current_block(if_fastobject); |
7359 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 7368 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
7360 checked_key = AddBoundsCheck(key, length); | 7369 checked_key = Add<HBoundsCheck>(key, length); |
7361 access = AddInstruction(BuildFastElementAccess( | 7370 access = AddInstruction(BuildFastElementAccess( |
7362 elements, checked_key, val, elements_kind_branch, | 7371 elements, checked_key, val, elements_kind_branch, |
7363 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7372 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
7364 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 7373 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
7365 if (is_store) { | 7374 if (is_store) { |
7366 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 7375 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
7367 } else { | 7376 } else { |
7368 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 7377 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
7369 } | 7378 } |
7370 } else { // External array elements. | 7379 } else { // External array elements. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7502 Push(graph()->GetArgumentsObject()); | 7511 Push(graph()->GetArgumentsObject()); |
7503 VisitForValue(expr->key()); | 7512 VisitForValue(expr->key()); |
7504 if (HasStackOverflow() || current_block() == NULL) return true; | 7513 if (HasStackOverflow() || current_block() == NULL) return true; |
7505 HValue* key = Pop(); | 7514 HValue* key = Pop(); |
7506 Drop(1); // Arguments object. | 7515 Drop(1); // Arguments object. |
7507 if (function_state()->outer() == NULL) { | 7516 if (function_state()->outer() == NULL) { |
7508 HInstruction* elements = AddInstruction( | 7517 HInstruction* elements = AddInstruction( |
7509 new(zone()) HArgumentsElements(false)); | 7518 new(zone()) HArgumentsElements(false)); |
7510 HInstruction* length = AddInstruction( | 7519 HInstruction* length = AddInstruction( |
7511 new(zone()) HArgumentsLength(elements)); | 7520 new(zone()) HArgumentsLength(elements)); |
7512 HInstruction* checked_key = AddBoundsCheck(key, length); | 7521 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
7513 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7522 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7514 } else { | 7523 } else { |
7515 EnsureArgumentsArePushedForAccess(); | 7524 EnsureArgumentsArePushedForAccess(); |
7516 | 7525 |
7517 // Number of arguments without receiver. | 7526 // Number of arguments without receiver. |
7518 HInstruction* elements = function_state()->arguments_elements(); | 7527 HInstruction* elements = function_state()->arguments_elements(); |
7519 int argument_count = environment()-> | 7528 int argument_count = environment()-> |
7520 arguments_environment()->parameter_count() - 1; | 7529 arguments_environment()->parameter_count() - 1; |
7521 HInstruction* length = AddInstruction(new(zone()) HConstant( | 7530 HInstruction* length = AddInstruction(new(zone()) HConstant( |
7522 argument_count)); | 7531 argument_count)); |
7523 HInstruction* checked_key = AddBoundsCheck(key, length); | 7532 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
7524 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7533 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7525 } | 7534 } |
7526 } | 7535 } |
7527 ast_context()->ReturnInstruction(result, expr->id()); | 7536 ast_context()->ReturnInstruction(result, expr->id()); |
7528 return true; | 7537 return true; |
7529 } | 7538 } |
7530 | 7539 |
7531 | 7540 |
7532 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7541 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
7533 ASSERT(!HasStackOverflow()); | 7542 ASSERT(!HasStackOverflow()); |
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8892 expr->target().is_identical_to(array_function); | 8901 expr->target().is_identical_to(array_function); |
8893 | 8902 |
8894 CHECK_ALIVE(VisitArgument(expr->expression())); | 8903 CHECK_ALIVE(VisitArgument(expr->expression())); |
8895 HValue* constructor = HPushArgument::cast(Top())->argument(); | 8904 HValue* constructor = HPushArgument::cast(Top())->argument(); |
8896 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8905 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
8897 HCallNew* call; | 8906 HCallNew* call; |
8898 if (use_call_new_array) { | 8907 if (use_call_new_array) { |
8899 Handle<Cell> cell = expr->allocation_info_cell(); | 8908 Handle<Cell> cell = expr->allocation_info_cell(); |
8900 AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); | 8909 AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); |
8901 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 8910 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
8902 cell); | 8911 cell, expr->elements_kind()); |
8903 } else { | 8912 } else { |
8904 call = new(zone()) HCallNew(context, constructor, argument_count); | 8913 call = new(zone()) HCallNew(context, constructor, argument_count); |
8905 } | 8914 } |
8906 Drop(argument_count); | 8915 Drop(argument_count); |
8907 call->set_position(expr->position()); | 8916 call->set_position(expr->position()); |
8908 return ast_context()->ReturnInstruction(call, expr->id()); | 8917 return ast_context()->ReturnInstruction(call, expr->id()); |
8909 } | 8918 } |
8910 } | 8919 } |
8911 | 8920 |
8912 | 8921 |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9342 if (i < 0 || i >= s->length()) { | 9351 if (i < 0 || i >= s->length()) { |
9343 return new(zone()) HConstant(OS::nan_value()); | 9352 return new(zone()) HConstant(OS::nan_value()); |
9344 } | 9353 } |
9345 return new(zone()) HConstant(s->Get(i)); | 9354 return new(zone()) HConstant(s->Get(i)); |
9346 } | 9355 } |
9347 } | 9356 } |
9348 BuildCheckNonSmi(string); | 9357 BuildCheckNonSmi(string); |
9349 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 9358 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
9350 HInstruction* length = HStringLength::New(zone(), string); | 9359 HInstruction* length = HStringLength::New(zone(), string); |
9351 AddInstruction(length); | 9360 AddInstruction(length); |
9352 HInstruction* checked_index = AddBoundsCheck(index, length); | 9361 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
9353 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 9362 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
9354 } | 9363 } |
9355 | 9364 |
9356 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 9365 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
9357 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 9366 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
9358 HValue* const32_minus_sa) { | 9367 HValue* const32_minus_sa) { |
9359 if (!const32_minus_sa->IsSub()) return false; | 9368 if (!const32_minus_sa->IsSub()) return false; |
9360 HSub* sub = HSub::cast(const32_minus_sa); | 9369 HSub* sub = HSub::cast(const32_minus_sa); |
9361 if (sa != sub->right()) return false; | 9370 if (sa != sub->right()) return false; |
9362 HValue* const32 = sub->left(); | 9371 HValue* const32 = sub->left(); |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9997 | 10006 |
9998 // Copy object elements if non-COW. | 10007 // Copy object elements if non-COW. |
9999 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, | 10008 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, |
10000 object_offset, elements_offset, elements_size); | 10009 object_offset, elements_offset, elements_size); |
10001 if (object_elements != NULL) { | 10010 if (object_elements != NULL) { |
10002 BuildEmitElements(elements, original_elements, kind, object_elements, | 10011 BuildEmitElements(elements, original_elements, kind, object_elements, |
10003 target, offset); | 10012 target, offset); |
10004 } | 10013 } |
10005 | 10014 |
10006 // Copy in-object properties. | 10015 // Copy in-object properties. |
10007 HValue* object_properties = | 10016 Handle<DescriptorArray> descriptors( |
10008 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 10017 boilerplate_object->map()->instance_descriptors()); |
10009 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, | 10018 int descriptor_count = boilerplate_object->map()->NumberOfOwnDescriptors(); |
10010 object_properties, target, offset); | 10019 bool has_field = false; |
| 10020 for (int i = 0; i < descriptor_count; i++) { |
| 10021 PropertyDetails details = descriptors->GetDetails(i); |
| 10022 if (details.type() != FIELD) continue; |
| 10023 has_field = true; |
| 10024 } |
| 10025 |
| 10026 if (has_field) { |
| 10027 HValue* object_properties = |
| 10028 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
| 10029 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
| 10030 object_properties, target, offset); |
| 10031 } |
10011 | 10032 |
10012 // Create allocation site info. | 10033 // Create allocation site info. |
10013 if (mode == TRACK_ALLOCATION_SITE && | 10034 if (mode == TRACK_ALLOCATION_SITE && |
10014 boilerplate_object->map()->CanTrackAllocationSite()) { | 10035 boilerplate_object->map()->CanTrackAllocationSite()) { |
10015 elements_offset += AllocationSiteInfo::kSize; | 10036 elements_offset += AllocationSiteInfo::kSize; |
10016 *offset += AllocationSiteInfo::kSize; | 10037 *offset += AllocationSiteInfo::kSize; |
10017 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( | 10038 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( |
10018 original_boilerplate_object)); | 10039 original_boilerplate_object)); |
10019 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 10040 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
10020 } | 10041 } |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10509 // Our implementation of arguments (based on this stack frame or an | 10530 // Our implementation of arguments (based on this stack frame or an |
10510 // adapter below it) does not work for inlined functions. This runtime | 10531 // adapter below it) does not work for inlined functions. This runtime |
10511 // function is blacklisted by AstNode::IsInlineable. | 10532 // function is blacklisted by AstNode::IsInlineable. |
10512 ASSERT(function_state()->outer() == NULL); | 10533 ASSERT(function_state()->outer() == NULL); |
10513 ASSERT(call->arguments()->length() == 1); | 10534 ASSERT(call->arguments()->length() == 1); |
10514 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 10535 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
10515 HValue* index = Pop(); | 10536 HValue* index = Pop(); |
10516 HInstruction* elements = AddInstruction( | 10537 HInstruction* elements = AddInstruction( |
10517 new(zone()) HArgumentsElements(false)); | 10538 new(zone()) HArgumentsElements(false)); |
10518 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); | 10539 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); |
10519 HInstruction* checked_index = AddBoundsCheck(index, length); | 10540 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
10520 HAccessArgumentsAt* result = | 10541 HAccessArgumentsAt* result = |
10521 new(zone()) HAccessArgumentsAt(elements, length, checked_index); | 10542 new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
10522 return ast_context()->ReturnInstruction(result, call->id()); | 10543 return ast_context()->ReturnInstruction(result, call->id()); |
10523 } | 10544 } |
10524 | 10545 |
10525 | 10546 |
10526 // Support for accessing the class and value fields of an object. | 10547 // Support for accessing the class and value fields of an object. |
10527 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { | 10548 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
10528 // The special form detected by IsClassOfTest is detected before we get here | 10549 // The special form detected by IsClassOfTest is detected before we get here |
10529 // and does not cause a bailout. | 10550 // and does not cause a bailout. |
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11584 } | 11605 } |
11585 } | 11606 } |
11586 | 11607 |
11587 #ifdef DEBUG | 11608 #ifdef DEBUG |
11588 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11609 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11589 if (allocator_ != NULL) allocator_->Verify(); | 11610 if (allocator_ != NULL) allocator_->Verify(); |
11590 #endif | 11611 #endif |
11591 } | 11612 } |
11592 | 11613 |
11593 } } // namespace v8::internal | 11614 } } // namespace v8::internal |
OLD | NEW |