| 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 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 | 1017 |
| 1018 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1018 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 1019 HBasicBlock* header = graph()->CreateBasicBlock(); | 1019 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 1020 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1020 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 1021 header->SetInitialEnvironment(entry_env); | 1021 header->SetInitialEnvironment(entry_env); |
| 1022 header->AttachLoopInformation(); | 1022 header->AttachLoopInformation(); |
| 1023 return header; | 1023 return header; |
| 1024 } | 1024 } |
| 1025 | 1025 |
| 1026 | 1026 |
| 1027 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { | 1027 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { |
| 1028 if (obj->type().IsHeapObject()) return obj; | 1028 if (obj->type().IsHeapObject()) return obj; |
| 1029 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); | 1029 HCheckHeapObject* check = new(zone()) HCheckHeapObject(obj); |
| 1030 AddInstruction(check); | 1030 AddInstruction(check); |
| 1031 return check; | 1031 return check; |
| 1032 } | 1032 } |
| 1033 | 1033 |
| 1034 | 1034 |
| 1035 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | 1035 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
| 1036 Handle<Map> map) { | 1036 Handle<Map> map) { |
| 1037 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); | 1037 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
| 1038 AddInstruction(check); | 1038 AddInstruction(check); |
| 1039 return check; | 1039 return check; |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 graph()->GetConstantUndefined()); | 1696 graph()->GetConstantUndefined()); |
| 1697 needs_or = true; | 1697 needs_or = true; |
| 1698 } | 1698 } |
| 1699 if (type->Maybe(Type::Undetectable())) { | 1699 if (type->Maybe(Type::Undetectable())) { |
| 1700 if (needs_or) if_nil.Or(); | 1700 if (needs_or) if_nil.Or(); |
| 1701 if_nil.If<HIsUndetectableAndBranch>(value); | 1701 if_nil.If<HIsUndetectableAndBranch>(value); |
| 1702 } else { | 1702 } else { |
| 1703 if_nil.Then(); | 1703 if_nil.Then(); |
| 1704 if_nil.Else(); | 1704 if_nil.Else(); |
| 1705 if (type->NumClasses() == 1) { | 1705 if (type->NumClasses() == 1) { |
| 1706 BuildCheckNonSmi(value); | 1706 BuildCheckHeapObject(value); |
| 1707 // For ICs, the map checked below is a sentinel map that gets replaced by | 1707 // For ICs, the map checked below is a sentinel map that gets replaced by |
| 1708 // the monomorphic map when the code is used as a template to generate a | 1708 // the monomorphic map when the code is used as a template to generate a |
| 1709 // new IC. For optimized functions, there is no sentinel map, the map | 1709 // new IC. For optimized functions, there is no sentinel map, the map |
| 1710 // emitted below is the actual monomorphic map. | 1710 // emitted below is the actual monomorphic map. |
| 1711 BuildCheckMap(value, type->Classes().Current()); | 1711 BuildCheckMap(value, type->Classes().Current()); |
| 1712 } else { | 1712 } else { |
| 1713 if_nil.Deopt(); | 1713 if_nil.Deopt(); |
| 1714 } | 1714 } |
| 1715 } | 1715 } |
| 1716 | 1716 |
| (...skipping 4449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6166 Map* transition = lookup->GetTransitionMapFromMap(*type); | 6166 Map* transition = lookup->GetTransitionMapFromMap(*type); |
| 6167 int descriptor = transition->LastAdded(); | 6167 int descriptor = transition->LastAdded(); |
| 6168 PropertyDetails details = | 6168 PropertyDetails details = |
| 6169 transition->instance_descriptors()->GetDetails(descriptor); | 6169 transition->instance_descriptors()->GetDetails(descriptor); |
| 6170 return details.representation(); | 6170 return details.representation(); |
| 6171 } | 6171 } |
| 6172 } | 6172 } |
| 6173 | 6173 |
| 6174 | 6174 |
| 6175 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { | 6175 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { |
| 6176 BuildCheckNonSmi(object); | 6176 BuildCheckHeapObject(object); |
| 6177 AddInstruction(HCheckMaps::New(object, map, zone())); | 6177 AddInstruction(HCheckMaps::New(object, map, zone())); |
| 6178 } | 6178 } |
| 6179 | 6179 |
| 6180 | 6180 |
| 6181 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, | 6181 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
| 6182 Handle<Map> map) { | 6182 Handle<Map> map) { |
| 6183 BuildCheckNonSmi(object); | 6183 BuildCheckHeapObject(object); |
| 6184 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); | 6184 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); |
| 6185 } | 6185 } |
| 6186 | 6186 |
| 6187 | 6187 |
| 6188 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( | 6188 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
| 6189 HValue* object, | 6189 HValue* object, |
| 6190 Handle<String> name, | 6190 Handle<String> name, |
| 6191 HValue* value, | 6191 HValue* value, |
| 6192 Handle<Map> map, | 6192 Handle<Map> map, |
| 6193 LookupResult* lookup) { | 6193 LookupResult* lookup) { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6342 } else if (access.IsInobject() != new_access.IsInobject()) { | 6342 } else if (access.IsInobject() != new_access.IsInobject()) { |
| 6343 // In-objectness did not match. | 6343 // In-objectness did not match. |
| 6344 break; | 6344 break; |
| 6345 } | 6345 } |
| 6346 representation = representation.generalize(new_representation); | 6346 representation = representation.generalize(new_representation); |
| 6347 } | 6347 } |
| 6348 | 6348 |
| 6349 if (count != types->length()) return NULL; | 6349 if (count != types->length()) return NULL; |
| 6350 | 6350 |
| 6351 // Everything matched; can use monomorphic load. | 6351 // Everything matched; can use monomorphic load. |
| 6352 BuildCheckNonSmi(object); | 6352 BuildCheckHeapObject(object); |
| 6353 AddInstruction(HCheckMaps::New(object, types, zone())); | 6353 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 6354 return BuildLoadNamedField(object, access, representation); | 6354 return BuildLoadNamedField(object, access, representation); |
| 6355 } | 6355 } |
| 6356 | 6356 |
| 6357 | 6357 |
| 6358 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 6358 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
| 6359 Property* expr, | 6359 Property* expr, |
| 6360 HValue* object, | 6360 HValue* object, |
| 6361 SmallMapList* types, | 6361 SmallMapList* types, |
| 6362 Handle<String> name) { | 6362 Handle<String> name) { |
| 6363 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( | 6363 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( |
| 6364 expr, object, types, name); | 6364 expr, object, types, name); |
| 6365 if (instr == NULL) { | 6365 if (instr == NULL) { |
| 6366 // Something did not match; must use a polymorphic load. | 6366 // Something did not match; must use a polymorphic load. |
| 6367 BuildCheckNonSmi(object); | 6367 BuildCheckHeapObject(object); |
| 6368 HValue* context = environment()->LookupContext(); | 6368 HValue* context = environment()->LookupContext(); |
| 6369 instr = new(zone()) HLoadNamedFieldPolymorphic( | 6369 instr = new(zone()) HLoadNamedFieldPolymorphic( |
| 6370 context, object, types, name, zone()); | 6370 context, object, types, name, zone()); |
| 6371 } | 6371 } |
| 6372 | 6372 |
| 6373 instr->set_position(expr->position()); | 6373 instr->set_position(expr->position()); |
| 6374 return ast_context()->ReturnInstruction(instr, expr->id()); | 6374 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 6375 } | 6375 } |
| 6376 | 6376 |
| 6377 | 6377 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6412 break; | 6412 break; |
| 6413 } else if (access.IsInobject() != new_access.IsInobject()) { | 6413 } else if (access.IsInobject() != new_access.IsInobject()) { |
| 6414 // In-objectness did not match. | 6414 // In-objectness did not match. |
| 6415 break; | 6415 break; |
| 6416 } | 6416 } |
| 6417 } | 6417 } |
| 6418 | 6418 |
| 6419 if (count != types->length()) return false; | 6419 if (count != types->length()) return false; |
| 6420 | 6420 |
| 6421 // Everything matched; can use monomorphic store. | 6421 // Everything matched; can use monomorphic store. |
| 6422 BuildCheckNonSmi(object); | 6422 BuildCheckHeapObject(object); |
| 6423 AddInstruction(HCheckMaps::New(object, types, zone())); | 6423 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 6424 HInstruction* store; | 6424 HInstruction* store; |
| 6425 CHECK_ALIVE_OR_RETURN( | 6425 CHECK_ALIVE_OR_RETURN( |
| 6426 store = BuildStoreNamedField(object, name, value, types->at(0), &lookup), | 6426 store = BuildStoreNamedField(object, name, value, types->at(0), &lookup), |
| 6427 true); | 6427 true); |
| 6428 Push(value); | 6428 Push(value); |
| 6429 store->set_position(expr->position()); | 6429 store->set_position(expr->position()); |
| 6430 AddInstruction(store); | 6430 AddInstruction(store); |
| 6431 AddSimulate(expr->AssignmentId()); | 6431 AddSimulate(expr->AssignmentId()); |
| 6432 ast_context()->ReturnValue(Pop()); | 6432 ast_context()->ReturnValue(Pop()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6447 // TODO(ager): We should recognize when the prototype chains for different | 6447 // TODO(ager): We should recognize when the prototype chains for different |
| 6448 // maps are identical. In that case we can avoid repeatedly generating the | 6448 // maps are identical. In that case we can avoid repeatedly generating the |
| 6449 // same prototype map checks. | 6449 // same prototype map checks. |
| 6450 int count = 0; | 6450 int count = 0; |
| 6451 HBasicBlock* join = NULL; | 6451 HBasicBlock* join = NULL; |
| 6452 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 6452 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
| 6453 Handle<Map> map = types->at(i); | 6453 Handle<Map> map = types->at(i); |
| 6454 LookupResult lookup(isolate()); | 6454 LookupResult lookup(isolate()); |
| 6455 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 6455 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
| 6456 if (count == 0) { | 6456 if (count == 0) { |
| 6457 BuildCheckNonSmi(object); | 6457 BuildCheckHeapObject(object); |
| 6458 join = graph()->CreateBasicBlock(); | 6458 join = graph()->CreateBasicBlock(); |
| 6459 } | 6459 } |
| 6460 ++count; | 6460 ++count; |
| 6461 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 6461 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 6462 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 6462 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 6463 HCompareMap* compare = | 6463 HCompareMap* compare = |
| 6464 new(zone()) HCompareMap(object, map, if_true, if_false); | 6464 new(zone()) HCompareMap(object, map, if_true, if_false); |
| 6465 current_block()->Finish(compare); | 6465 current_block()->Finish(compare); |
| 6466 | 6466 |
| 6467 set_current_block(if_true); | 6467 set_current_block(if_true); |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7192 HValue* object, | 7192 HValue* object, |
| 7193 HValue* key, | 7193 HValue* key, |
| 7194 HValue* val, | 7194 HValue* val, |
| 7195 Expression* prop, | 7195 Expression* prop, |
| 7196 BailoutId ast_id, | 7196 BailoutId ast_id, |
| 7197 int position, | 7197 int position, |
| 7198 bool is_store, | 7198 bool is_store, |
| 7199 KeyedAccessStoreMode store_mode, | 7199 KeyedAccessStoreMode store_mode, |
| 7200 bool* has_side_effects) { | 7200 bool* has_side_effects) { |
| 7201 *has_side_effects = false; | 7201 *has_side_effects = false; |
| 7202 BuildCheckNonSmi(object); | 7202 BuildCheckHeapObject(object); |
| 7203 SmallMapList* maps = prop->GetReceiverTypes(); | 7203 SmallMapList* maps = prop->GetReceiverTypes(); |
| 7204 bool todo_external_array = false; | 7204 bool todo_external_array = false; |
| 7205 | 7205 |
| 7206 if (!is_store) { | 7206 if (!is_store) { |
| 7207 HInstruction* consolidated_load = | 7207 HInstruction* consolidated_load = |
| 7208 TryBuildConsolidatedElementLoad(object, key, val, maps); | 7208 TryBuildConsolidatedElementLoad(object, key, val, maps); |
| 7209 if (consolidated_load != NULL) { | 7209 if (consolidated_load != NULL) { |
| 7210 *has_side_effects |= consolidated_load->HasObservableSideEffects(); | 7210 *has_side_effects |= consolidated_load->HasObservableSideEffects(); |
| 7211 if (position != RelocInfo::kNoPosition) { | 7211 if (position != RelocInfo::kNoPosition) { |
| 7212 consolidated_load->set_position(position); | 7212 consolidated_load->set_position(position); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7417 bool* has_side_effects) { | 7417 bool* has_side_effects) { |
| 7418 ASSERT(!expr->IsPropertyName()); | 7418 ASSERT(!expr->IsPropertyName()); |
| 7419 HInstruction* instr = NULL; | 7419 HInstruction* instr = NULL; |
| 7420 if (expr->IsMonomorphic()) { | 7420 if (expr->IsMonomorphic()) { |
| 7421 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 7421 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 7422 if (map->has_slow_elements_kind()) { | 7422 if (map->has_slow_elements_kind()) { |
| 7423 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) | 7423 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) |
| 7424 : BuildLoadKeyedGeneric(obj, key); | 7424 : BuildLoadKeyedGeneric(obj, key); |
| 7425 AddInstruction(instr); | 7425 AddInstruction(instr); |
| 7426 } else { | 7426 } else { |
| 7427 BuildCheckNonSmi(obj); | 7427 BuildCheckHeapObject(obj); |
| 7428 instr = BuildMonomorphicElementAccess( | 7428 instr = BuildMonomorphicElementAccess( |
| 7429 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); | 7429 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); |
| 7430 } | 7430 } |
| 7431 } else if (expr->GetReceiverTypes() != NULL && | 7431 } else if (expr->GetReceiverTypes() != NULL && |
| 7432 !expr->GetReceiverTypes()->is_empty()) { | 7432 !expr->GetReceiverTypes()->is_empty()) { |
| 7433 return HandlePolymorphicElementAccess( | 7433 return HandlePolymorphicElementAccess( |
| 7434 obj, key, val, expr, ast_id, position, is_store, | 7434 obj, key, val, expr, ast_id, position, is_store, |
| 7435 expr->GetStoreMode(), has_side_effects); | 7435 expr->GetStoreMode(), has_side_effects); |
| 7436 } else { | 7436 } else { |
| 7437 if (is_store) { | 7437 if (is_store) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7549 ASSERT(current_block() != NULL); | 7549 ASSERT(current_block() != NULL); |
| 7550 ASSERT(current_block()->HasPredecessor()); | 7550 ASSERT(current_block()->HasPredecessor()); |
| 7551 | 7551 |
| 7552 if (TryArgumentsAccess(expr)) return; | 7552 if (TryArgumentsAccess(expr)) return; |
| 7553 | 7553 |
| 7554 CHECK_ALIVE(VisitForValue(expr->obj())); | 7554 CHECK_ALIVE(VisitForValue(expr->obj())); |
| 7555 | 7555 |
| 7556 HInstruction* instr = NULL; | 7556 HInstruction* instr = NULL; |
| 7557 if (expr->IsStringLength()) { | 7557 if (expr->IsStringLength()) { |
| 7558 HValue* string = Pop(); | 7558 HValue* string = Pop(); |
| 7559 BuildCheckNonSmi(string); | 7559 BuildCheckHeapObject(string); |
| 7560 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 7560 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 7561 instr = HStringLength::New(zone(), string); | 7561 instr = HStringLength::New(zone(), string); |
| 7562 } else if (expr->IsStringAccess()) { | 7562 } else if (expr->IsStringAccess()) { |
| 7563 CHECK_ALIVE(VisitForValue(expr->key())); | 7563 CHECK_ALIVE(VisitForValue(expr->key())); |
| 7564 HValue* index = Pop(); | 7564 HValue* index = Pop(); |
| 7565 HValue* string = Pop(); | 7565 HValue* string = Pop(); |
| 7566 HValue* context = environment()->LookupContext(); | 7566 HValue* context = environment()->LookupContext(); |
| 7567 HInstruction* char_code = | 7567 HInstruction* char_code = |
| 7568 BuildStringCharCodeAt(context, string, index); | 7568 BuildStringCharCodeAt(context, string, index); |
| 7569 AddInstruction(char_code); | 7569 AddInstruction(char_code); |
| 7570 instr = HStringCharFromCode::New(zone(), context, char_code); | 7570 instr = HStringCharFromCode::New(zone(), context, char_code); |
| 7571 | 7571 |
| 7572 } else if (expr->IsFunctionPrototype()) { | 7572 } else if (expr->IsFunctionPrototype()) { |
| 7573 HValue* function = Pop(); | 7573 HValue* function = Pop(); |
| 7574 BuildCheckNonSmi(function); | 7574 BuildCheckHeapObject(function); |
| 7575 instr = new(zone()) HLoadFunctionPrototype(function); | 7575 instr = new(zone()) HLoadFunctionPrototype(function); |
| 7576 | 7576 |
| 7577 } else if (expr->key()->IsPropertyName()) { | 7577 } else if (expr->key()->IsPropertyName()) { |
| 7578 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7578 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 7579 SmallMapList* types = expr->GetReceiverTypes(); | 7579 SmallMapList* types = expr->GetReceiverTypes(); |
| 7580 HValue* object = Top(); | 7580 HValue* object = Top(); |
| 7581 | 7581 |
| 7582 Handle<Map> map; | 7582 Handle<Map> map; |
| 7583 bool monomorphic = false; | 7583 bool monomorphic = false; |
| 7584 if (expr->IsMonomorphic()) { | 7584 if (expr->IsMonomorphic()) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7738 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); | 7738 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); |
| 7739 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); | 7739 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); |
| 7740 number_block = graph()->CreateBasicBlock(); | 7740 number_block = graph()->CreateBasicBlock(); |
| 7741 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); | 7741 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); |
| 7742 smicheck->SetSuccessorAt(0, empty_smi_block); | 7742 smicheck->SetSuccessorAt(0, empty_smi_block); |
| 7743 smicheck->SetSuccessorAt(1, not_smi_block); | 7743 smicheck->SetSuccessorAt(1, not_smi_block); |
| 7744 current_block()->Finish(smicheck); | 7744 current_block()->Finish(smicheck); |
| 7745 empty_smi_block->Goto(number_block); | 7745 empty_smi_block->Goto(number_block); |
| 7746 set_current_block(not_smi_block); | 7746 set_current_block(not_smi_block); |
| 7747 } else { | 7747 } else { |
| 7748 BuildCheckNonSmi(receiver); | 7748 BuildCheckHeapObject(receiver); |
| 7749 } | 7749 } |
| 7750 } | 7750 } |
| 7751 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7751 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 7752 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7752 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 7753 HUnaryControlInstruction* compare; | 7753 HUnaryControlInstruction* compare; |
| 7754 | 7754 |
| 7755 if (handle_smi && map.is_identical_to(number_marker_map)) { | 7755 if (handle_smi && map.is_identical_to(number_marker_map)) { |
| 7756 compare = new(zone()) HCompareMap( | 7756 compare = new(zone()) HCompareMap( |
| 7757 receiver, heap_number_map, if_true, if_false); | 7757 receiver, heap_number_map, if_true, if_false); |
| 7758 map = initial_number_map; | 7758 map = initial_number_map; |
| (...skipping 1649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9408 HConstant* c_index = HConstant::cast(index); | 9408 HConstant* c_index = HConstant::cast(index); |
| 9409 if (c_string->HasStringValue() && c_index->HasNumberValue()) { | 9409 if (c_string->HasStringValue() && c_index->HasNumberValue()) { |
| 9410 int32_t i = c_index->NumberValueAsInteger32(); | 9410 int32_t i = c_index->NumberValueAsInteger32(); |
| 9411 Handle<String> s = c_string->StringValue(); | 9411 Handle<String> s = c_string->StringValue(); |
| 9412 if (i < 0 || i >= s->length()) { | 9412 if (i < 0 || i >= s->length()) { |
| 9413 return new(zone()) HConstant(OS::nan_value()); | 9413 return new(zone()) HConstant(OS::nan_value()); |
| 9414 } | 9414 } |
| 9415 return new(zone()) HConstant(s->Get(i)); | 9415 return new(zone()) HConstant(s->Get(i)); |
| 9416 } | 9416 } |
| 9417 } | 9417 } |
| 9418 BuildCheckNonSmi(string); | 9418 BuildCheckHeapObject(string); |
| 9419 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 9419 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 9420 HInstruction* length = HStringLength::New(zone(), string); | 9420 HInstruction* length = HStringLength::New(zone(), string); |
| 9421 AddInstruction(length); | 9421 AddInstruction(length); |
| 9422 HInstruction* checked_index = AddBoundsCheck(index, length); | 9422 HInstruction* checked_index = AddBoundsCheck(index, length); |
| 9423 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 9423 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 9424 } | 9424 } |
| 9425 | 9425 |
| 9426 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 9426 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
| 9427 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 9427 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
| 9428 HValue* const32_minus_sa) { | 9428 HValue* const32_minus_sa) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9499 left_type = handle(Type::Any(), isolate()); | 9499 left_type = handle(Type::Any(), isolate()); |
| 9500 } | 9500 } |
| 9501 if (right_type->Is(Type::None())) { | 9501 if (right_type->Is(Type::None())) { |
| 9502 AddSoftDeoptimize(); | 9502 AddSoftDeoptimize(); |
| 9503 right_type = handle(Type::Any(), isolate()); | 9503 right_type = handle(Type::Any(), isolate()); |
| 9504 } | 9504 } |
| 9505 HInstruction* instr = NULL; | 9505 HInstruction* instr = NULL; |
| 9506 switch (expr->op()) { | 9506 switch (expr->op()) { |
| 9507 case Token::ADD: | 9507 case Token::ADD: |
| 9508 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { | 9508 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { |
| 9509 BuildCheckNonSmi(left); | 9509 BuildCheckHeapObject(left); |
| 9510 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 9510 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
| 9511 BuildCheckNonSmi(right); | 9511 BuildCheckHeapObject(right); |
| 9512 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 9512 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
| 9513 instr = HStringAdd::New(zone(), context, left, right); | 9513 instr = HStringAdd::New(zone(), context, left, right); |
| 9514 } else { | 9514 } else { |
| 9515 instr = HAdd::New(zone(), context, left, right); | 9515 instr = HAdd::New(zone(), context, left, right); |
| 9516 } | 9516 } |
| 9517 break; | 9517 break; |
| 9518 case Token::SUB: | 9518 case Token::SUB: |
| 9519 instr = HSub::New(zone(), context, left, right); | 9519 instr = HSub::New(zone(), context, left, right); |
| 9520 break; | 9520 break; |
| 9521 case Token::MUL: | 9521 case Token::MUL: |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9923 // Can we get away with map check and not instance type check? | 9923 // Can we get away with map check and not instance type check? |
| 9924 if (overall_type->IsClass()) { | 9924 if (overall_type->IsClass()) { |
| 9925 Handle<Map> map = overall_type->AsClass(); | 9925 Handle<Map> map = overall_type->AsClass(); |
| 9926 AddCheckMapsWithTransitions(left, map); | 9926 AddCheckMapsWithTransitions(left, map); |
| 9927 AddCheckMapsWithTransitions(right, map); | 9927 AddCheckMapsWithTransitions(right, map); |
| 9928 HCompareObjectEqAndBranch* result = | 9928 HCompareObjectEqAndBranch* result = |
| 9929 new(zone()) HCompareObjectEqAndBranch(left, right); | 9929 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 9930 result->set_position(expr->position()); | 9930 result->set_position(expr->position()); |
| 9931 return ast_context()->ReturnControl(result, expr->id()); | 9931 return ast_context()->ReturnControl(result, expr->id()); |
| 9932 } else { | 9932 } else { |
| 9933 BuildCheckNonSmi(left); | 9933 BuildCheckHeapObject(left); |
| 9934 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); | 9934 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
| 9935 BuildCheckNonSmi(right); | 9935 BuildCheckHeapObject(right); |
| 9936 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); | 9936 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
| 9937 HCompareObjectEqAndBranch* result = | 9937 HCompareObjectEqAndBranch* result = |
| 9938 new(zone()) HCompareObjectEqAndBranch(left, right); | 9938 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 9939 result->set_position(expr->position()); | 9939 result->set_position(expr->position()); |
| 9940 return ast_context()->ReturnControl(result, expr->id()); | 9940 return ast_context()->ReturnControl(result, expr->id()); |
| 9941 } | 9941 } |
| 9942 } | 9942 } |
| 9943 default: | 9943 default: |
| 9944 return Bailout("Unsupported non-primitive compare"); | 9944 return Bailout("Unsupported non-primitive compare"); |
| 9945 } | 9945 } |
| 9946 } else if (overall_type->Is(Type::InternalizedString()) && | 9946 } else if (overall_type->Is(Type::InternalizedString()) && |
| 9947 Token::IsEqualityOp(op)) { | 9947 Token::IsEqualityOp(op)) { |
| 9948 BuildCheckNonSmi(left); | 9948 BuildCheckHeapObject(left); |
| 9949 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); | 9949 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); |
| 9950 BuildCheckNonSmi(right); | 9950 BuildCheckHeapObject(right); |
| 9951 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); | 9951 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); |
| 9952 HCompareObjectEqAndBranch* result = | 9952 HCompareObjectEqAndBranch* result = |
| 9953 new(zone()) HCompareObjectEqAndBranch(left, right); | 9953 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 9954 result->set_position(expr->position()); | 9954 result->set_position(expr->position()); |
| 9955 return ast_context()->ReturnControl(result, expr->id()); | 9955 return ast_context()->ReturnControl(result, expr->id()); |
| 9956 } else { | 9956 } else { |
| 9957 if (combined_rep.IsTagged() || combined_rep.IsNone()) { | 9957 if (combined_rep.IsTagged() || combined_rep.IsNone()) { |
| 9958 HCompareGeneric* result = | 9958 HCompareGeneric* result = |
| 9959 new(zone()) HCompareGeneric(context, left, right, op); | 9959 new(zone()) HCompareGeneric(context, left, right, op); |
| 9960 result->set_observed_input_representation(1, left_rep); | 9960 result->set_observed_input_representation(1, left_rep); |
| (...skipping 1696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11657 } | 11657 } |
| 11658 } | 11658 } |
| 11659 | 11659 |
| 11660 #ifdef DEBUG | 11660 #ifdef DEBUG |
| 11661 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11661 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11662 if (allocator_ != NULL) allocator_->Verify(); | 11662 if (allocator_ != NULL) allocator_->Verify(); |
| 11663 #endif | 11663 #endif |
| 11664 } | 11664 } |
| 11665 | 11665 |
| 11666 } } // namespace v8::internal | 11666 } } // namespace v8::internal |
| OLD | NEW |