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 |