| 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 4298 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 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6600 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6600 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
| 6601 Variable* var, | 6601 Variable* var, |
| 6602 HValue* value, | 6602 HValue* value, |
| 6603 int position, | 6603 int position, |
| 6604 BailoutId ast_id) { | 6604 BailoutId ast_id) { |
| 6605 LookupResult lookup(isolate()); | 6605 LookupResult lookup(isolate()); |
| 6606 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6606 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
| 6607 if (type == kUseCell) { | 6607 if (type == kUseCell) { |
| 6608 Handle<GlobalObject> global(current_info()->global_object()); | 6608 Handle<GlobalObject> global(current_info()->global_object()); |
| 6609 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 6609 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 6610 if (cell->type()->IsConstant()) { |
| 6611 AddSoftDeoptimize(); |
| 6612 } |
| 6610 HInstruction* instr = | 6613 HInstruction* instr = |
| 6611 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6614 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
| 6612 instr->set_position(position); | 6615 instr->set_position(position); |
| 6613 AddInstruction(instr); | 6616 AddInstruction(instr); |
| 6614 if (instr->HasObservableSideEffects()) { | 6617 if (instr->HasObservableSideEffects()) { |
| 6615 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6618 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
| 6616 } | 6619 } |
| 6617 } else { | 6620 } else { |
| 6618 HValue* context = environment()->LookupContext(); | 6621 HValue* context = environment()->LookupContext(); |
| 6619 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6622 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7304 elements_kind <= LAST_ELEMENTS_KIND; | 7307 elements_kind <= LAST_ELEMENTS_KIND; |
| 7305 elements_kind = ElementsKind(elements_kind + 1)) { | 7308 elements_kind = ElementsKind(elements_kind + 1)) { |
| 7306 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some | 7309 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some |
| 7307 // code that's executed for all external array cases. | 7310 // code that's executed for all external array cases. |
| 7308 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == | 7311 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == |
| 7309 LAST_ELEMENTS_KIND); | 7312 LAST_ELEMENTS_KIND); |
| 7310 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND | 7313 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
| 7311 && todo_external_array) { | 7314 && todo_external_array) { |
| 7312 HInstruction* length = | 7315 HInstruction* length = |
| 7313 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 7316 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 7314 checked_key = AddBoundsCheck(key, length); | 7317 checked_key = Add<HBoundsCheck>(key, length); |
| 7315 external_elements = new(zone()) HLoadExternalArrayPointer(elements); | 7318 external_elements = new(zone()) HLoadExternalArrayPointer(elements); |
| 7316 AddInstruction(external_elements); | 7319 AddInstruction(external_elements); |
| 7317 } | 7320 } |
| 7318 if (type_todo[elements_kind]) { | 7321 if (type_todo[elements_kind]) { |
| 7319 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7322 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 7320 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7323 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 7321 HCompareConstantEqAndBranch* elements_kind_branch = | 7324 HCompareConstantEqAndBranch* elements_kind_branch = |
| 7322 new(zone()) HCompareConstantEqAndBranch( | 7325 new(zone()) HCompareConstantEqAndBranch( |
| 7323 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 7326 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
| 7324 elements_kind_branch->SetSuccessorAt(0, if_true); | 7327 elements_kind_branch->SetSuccessorAt(0, if_true); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 7347 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 7350 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
| 7348 typecheck->SetSuccessorAt(0, if_jsarray); | 7351 typecheck->SetSuccessorAt(0, if_jsarray); |
| 7349 typecheck->SetSuccessorAt(1, if_fastobject); | 7352 typecheck->SetSuccessorAt(1, if_fastobject); |
| 7350 current_block()->Finish(typecheck); | 7353 current_block()->Finish(typecheck); |
| 7351 | 7354 |
| 7352 set_current_block(if_jsarray); | 7355 set_current_block(if_jsarray); |
| 7353 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), | 7356 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), |
| 7354 typecheck, Representation::Smi()); | 7357 typecheck, Representation::Smi()); |
| 7355 length->set_type(HType::Smi()); | 7358 length->set_type(HType::Smi()); |
| 7356 | 7359 |
| 7357 checked_key = AddBoundsCheck(key, length); | 7360 checked_key = Add<HBoundsCheck>(key, length); |
| 7358 access = AddInstruction(BuildFastElementAccess( | 7361 access = AddInstruction(BuildFastElementAccess( |
| 7359 elements, checked_key, val, elements_kind_branch, | 7362 elements, checked_key, val, elements_kind_branch, |
| 7360 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7363 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
| 7361 if (!is_store) { | 7364 if (!is_store) { |
| 7362 Push(access); | 7365 Push(access); |
| 7363 } | 7366 } |
| 7364 | 7367 |
| 7365 *has_side_effects |= access->HasObservableSideEffects(); | 7368 *has_side_effects |= access->HasObservableSideEffects(); |
| 7366 // The caller will use has_side_effects and add correct Simulate. | 7369 // The caller will use has_side_effects and add correct Simulate. |
| 7367 access->SetFlag(HValue::kHasNoObservableSideEffects); | 7370 access->SetFlag(HValue::kHasNoObservableSideEffects); |
| 7368 if (position != -1) { | 7371 if (position != -1) { |
| 7369 access->set_position(position); | 7372 access->set_position(position); |
| 7370 } | 7373 } |
| 7371 if_jsarray->GotoNoSimulate(join); | 7374 if_jsarray->GotoNoSimulate(join); |
| 7372 | 7375 |
| 7373 set_current_block(if_fastobject); | 7376 set_current_block(if_fastobject); |
| 7374 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 7377 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 7375 checked_key = AddBoundsCheck(key, length); | 7378 checked_key = Add<HBoundsCheck>(key, length); |
| 7376 access = AddInstruction(BuildFastElementAccess( | 7379 access = AddInstruction(BuildFastElementAccess( |
| 7377 elements, checked_key, val, elements_kind_branch, | 7380 elements, checked_key, val, elements_kind_branch, |
| 7378 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7381 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
| 7379 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 7382 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
| 7380 if (is_store) { | 7383 if (is_store) { |
| 7381 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 7384 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
| 7382 } else { | 7385 } else { |
| 7383 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 7386 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
| 7384 } | 7387 } |
| 7385 } else { // External array elements. | 7388 } else { // External array elements. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7517 Push(graph()->GetArgumentsObject()); | 7520 Push(graph()->GetArgumentsObject()); |
| 7518 VisitForValue(expr->key()); | 7521 VisitForValue(expr->key()); |
| 7519 if (HasStackOverflow() || current_block() == NULL) return true; | 7522 if (HasStackOverflow() || current_block() == NULL) return true; |
| 7520 HValue* key = Pop(); | 7523 HValue* key = Pop(); |
| 7521 Drop(1); // Arguments object. | 7524 Drop(1); // Arguments object. |
| 7522 if (function_state()->outer() == NULL) { | 7525 if (function_state()->outer() == NULL) { |
| 7523 HInstruction* elements = AddInstruction( | 7526 HInstruction* elements = AddInstruction( |
| 7524 new(zone()) HArgumentsElements(false)); | 7527 new(zone()) HArgumentsElements(false)); |
| 7525 HInstruction* length = AddInstruction( | 7528 HInstruction* length = AddInstruction( |
| 7526 new(zone()) HArgumentsLength(elements)); | 7529 new(zone()) HArgumentsLength(elements)); |
| 7527 HInstruction* checked_key = AddBoundsCheck(key, length); | 7530 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 7528 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7531 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| 7529 } else { | 7532 } else { |
| 7530 EnsureArgumentsArePushedForAccess(); | 7533 EnsureArgumentsArePushedForAccess(); |
| 7531 | 7534 |
| 7532 // Number of arguments without receiver. | 7535 // Number of arguments without receiver. |
| 7533 HInstruction* elements = function_state()->arguments_elements(); | 7536 HInstruction* elements = function_state()->arguments_elements(); |
| 7534 int argument_count = environment()-> | 7537 int argument_count = environment()-> |
| 7535 arguments_environment()->parameter_count() - 1; | 7538 arguments_environment()->parameter_count() - 1; |
| 7536 HInstruction* length = AddInstruction(new(zone()) HConstant( | 7539 HInstruction* length = AddInstruction(new(zone()) HConstant( |
| 7537 argument_count)); | 7540 argument_count)); |
| 7538 HInstruction* checked_key = AddBoundsCheck(key, length); | 7541 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 7539 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7542 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| 7540 } | 7543 } |
| 7541 } | 7544 } |
| 7542 ast_context()->ReturnInstruction(result, expr->id()); | 7545 ast_context()->ReturnInstruction(result, expr->id()); |
| 7543 return true; | 7546 return true; |
| 7544 } | 7547 } |
| 7545 | 7548 |
| 7546 | 7549 |
| 7547 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7550 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
| 7548 ASSERT(!HasStackOverflow()); | 7551 ASSERT(!HasStackOverflow()); |
| (...skipping 1863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9412 if (i < 0 || i >= s->length()) { | 9415 if (i < 0 || i >= s->length()) { |
| 9413 return new(zone()) HConstant(OS::nan_value()); | 9416 return new(zone()) HConstant(OS::nan_value()); |
| 9414 } | 9417 } |
| 9415 return new(zone()) HConstant(s->Get(i)); | 9418 return new(zone()) HConstant(s->Get(i)); |
| 9416 } | 9419 } |
| 9417 } | 9420 } |
| 9418 BuildCheckNonSmi(string); | 9421 BuildCheckNonSmi(string); |
| 9419 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 9422 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 9420 HInstruction* length = HStringLength::New(zone(), string); | 9423 HInstruction* length = HStringLength::New(zone(), string); |
| 9421 AddInstruction(length); | 9424 AddInstruction(length); |
| 9422 HInstruction* checked_index = AddBoundsCheck(index, length); | 9425 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
| 9423 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 9426 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 9424 } | 9427 } |
| 9425 | 9428 |
| 9426 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 9429 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
| 9427 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 9430 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
| 9428 HValue* const32_minus_sa) { | 9431 HValue* const32_minus_sa) { |
| 9429 if (!const32_minus_sa->IsSub()) return false; | 9432 if (!const32_minus_sa->IsSub()) return false; |
| 9430 HSub* sub = HSub::cast(const32_minus_sa); | 9433 HSub* sub = HSub::cast(const32_minus_sa); |
| 9431 if (sa != sub->right()) return false; | 9434 if (sa != sub->right()) return false; |
| 9432 HValue* const32 = sub->left(); | 9435 HValue* const32 = sub->left(); |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10069 | 10072 |
| 10070 // Copy object elements if non-COW. | 10073 // Copy object elements if non-COW. |
| 10071 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, | 10074 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, |
| 10072 object_offset, elements_offset, elements_size); | 10075 object_offset, elements_offset, elements_size); |
| 10073 if (object_elements != NULL) { | 10076 if (object_elements != NULL) { |
| 10074 BuildEmitElements(elements, original_elements, kind, object_elements, | 10077 BuildEmitElements(elements, original_elements, kind, object_elements, |
| 10075 target, offset); | 10078 target, offset); |
| 10076 } | 10079 } |
| 10077 | 10080 |
| 10078 // Copy in-object properties. | 10081 // Copy in-object properties. |
| 10079 HValue* object_properties = | 10082 Handle<DescriptorArray> descriptors( |
| 10080 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 10083 boilerplate_object->map()->instance_descriptors()); |
| 10081 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, | 10084 int descriptor_count = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 10082 object_properties, target, offset); | 10085 bool has_field = false; |
| 10086 for (int i = 0; i < descriptor_count; i++) { |
| 10087 PropertyDetails details = descriptors->GetDetails(i); |
| 10088 if (details.type() != FIELD) continue; |
| 10089 has_field = true; |
| 10090 } |
| 10091 |
| 10092 if (has_field) { |
| 10093 HValue* object_properties = |
| 10094 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
| 10095 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
| 10096 object_properties, target, offset); |
| 10097 } |
| 10083 | 10098 |
| 10084 // Create allocation site info. | 10099 // Create allocation site info. |
| 10085 if (mode == TRACK_ALLOCATION_SITE && | 10100 if (mode == TRACK_ALLOCATION_SITE && |
| 10086 boilerplate_object->map()->CanTrackAllocationSite()) { | 10101 boilerplate_object->map()->CanTrackAllocationSite()) { |
| 10087 elements_offset += AllocationSiteInfo::kSize; | 10102 elements_offset += AllocationSiteInfo::kSize; |
| 10088 *offset += AllocationSiteInfo::kSize; | 10103 *offset += AllocationSiteInfo::kSize; |
| 10089 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( | 10104 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( |
| 10090 original_boilerplate_object)); | 10105 original_boilerplate_object)); |
| 10091 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 10106 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
| 10092 } | 10107 } |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10581 // Our implementation of arguments (based on this stack frame or an | 10596 // Our implementation of arguments (based on this stack frame or an |
| 10582 // adapter below it) does not work for inlined functions. This runtime | 10597 // adapter below it) does not work for inlined functions. This runtime |
| 10583 // function is blacklisted by AstNode::IsInlineable. | 10598 // function is blacklisted by AstNode::IsInlineable. |
| 10584 ASSERT(function_state()->outer() == NULL); | 10599 ASSERT(function_state()->outer() == NULL); |
| 10585 ASSERT(call->arguments()->length() == 1); | 10600 ASSERT(call->arguments()->length() == 1); |
| 10586 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 10601 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 10587 HValue* index = Pop(); | 10602 HValue* index = Pop(); |
| 10588 HInstruction* elements = AddInstruction( | 10603 HInstruction* elements = AddInstruction( |
| 10589 new(zone()) HArgumentsElements(false)); | 10604 new(zone()) HArgumentsElements(false)); |
| 10590 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); | 10605 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); |
| 10591 HInstruction* checked_index = AddBoundsCheck(index, length); | 10606 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
| 10592 HAccessArgumentsAt* result = | 10607 HAccessArgumentsAt* result = |
| 10593 new(zone()) HAccessArgumentsAt(elements, length, checked_index); | 10608 new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
| 10594 return ast_context()->ReturnInstruction(result, call->id()); | 10609 return ast_context()->ReturnInstruction(result, call->id()); |
| 10595 } | 10610 } |
| 10596 | 10611 |
| 10597 | 10612 |
| 10598 // Support for accessing the class and value fields of an object. | 10613 // Support for accessing the class and value fields of an object. |
| 10599 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { | 10614 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
| 10600 // The special form detected by IsClassOfTest is detected before we get here | 10615 // The special form detected by IsClassOfTest is detected before we get here |
| 10601 // and does not cause a bailout. | 10616 // and does not cause a bailout. |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11654 } | 11669 } |
| 11655 } | 11670 } |
| 11656 | 11671 |
| 11657 #ifdef DEBUG | 11672 #ifdef DEBUG |
| 11658 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11673 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11659 if (allocator_ != NULL) allocator_->Verify(); | 11674 if (allocator_ != NULL) allocator_->Verify(); |
| 11660 #endif | 11675 #endif |
| 11661 } | 11676 } |
| 11662 | 11677 |
| 11663 } } // namespace v8::internal | 11678 } } // namespace v8::internal |
| OLD | NEW |