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 |