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 4434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6151 Map* transition = lookup->GetTransitionMapFromMap(*type); | 6151 Map* transition = lookup->GetTransitionMapFromMap(*type); |
6152 int descriptor = transition->LastAdded(); | 6152 int descriptor = transition->LastAdded(); |
6153 PropertyDetails details = | 6153 PropertyDetails details = |
6154 transition->instance_descriptors()->GetDetails(descriptor); | 6154 transition->instance_descriptors()->GetDetails(descriptor); |
6155 return details.representation(); | 6155 return details.representation(); |
6156 } | 6156 } |
6157 } | 6157 } |
6158 | 6158 |
6159 | 6159 |
6160 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { | 6160 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { |
6161 BuildCheckNonSmi(object); | 6161 BuildCheckHeapObject(object); |
6162 AddInstruction(HCheckMaps::New(object, map, zone())); | 6162 AddInstruction(HCheckMaps::New(object, map, zone())); |
6163 } | 6163 } |
6164 | 6164 |
6165 | 6165 |
6166 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, | 6166 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
6167 Handle<Map> map) { | 6167 Handle<Map> map) { |
6168 BuildCheckNonSmi(object); | 6168 BuildCheckHeapObject(object); |
6169 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); | 6169 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); |
6170 } | 6170 } |
6171 | 6171 |
6172 | 6172 |
6173 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( | 6173 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
6174 HValue* object, | 6174 HValue* object, |
6175 Handle<String> name, | 6175 Handle<String> name, |
6176 HValue* value, | 6176 HValue* value, |
6177 Handle<Map> map, | 6177 Handle<Map> map, |
6178 LookupResult* lookup) { | 6178 LookupResult* lookup) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6327 } else if (access.IsInobject() != new_access.IsInobject()) { | 6327 } else if (access.IsInobject() != new_access.IsInobject()) { |
6328 // In-objectness did not match. | 6328 // In-objectness did not match. |
6329 break; | 6329 break; |
6330 } | 6330 } |
6331 representation = representation.generalize(new_representation); | 6331 representation = representation.generalize(new_representation); |
6332 } | 6332 } |
6333 | 6333 |
6334 if (count != types->length()) return NULL; | 6334 if (count != types->length()) return NULL; |
6335 | 6335 |
6336 // Everything matched; can use monomorphic load. | 6336 // Everything matched; can use monomorphic load. |
6337 BuildCheckNonSmi(object); | 6337 BuildCheckHeapObject(object); |
6338 AddInstruction(HCheckMaps::New(object, types, zone())); | 6338 AddInstruction(HCheckMaps::New(object, types, zone())); |
6339 return BuildLoadNamedField(object, access, representation); | 6339 return BuildLoadNamedField(object, access, representation); |
6340 } | 6340 } |
6341 | 6341 |
6342 | 6342 |
6343 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 6343 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
6344 Property* expr, | 6344 Property* expr, |
6345 HValue* object, | 6345 HValue* object, |
6346 SmallMapList* types, | 6346 SmallMapList* types, |
6347 Handle<String> name) { | 6347 Handle<String> name) { |
6348 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( | 6348 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( |
6349 expr, object, types, name); | 6349 expr, object, types, name); |
6350 if (instr == NULL) { | 6350 if (instr == NULL) { |
6351 // Something did not match; must use a polymorphic load. | 6351 // Something did not match; must use a polymorphic load. |
6352 BuildCheckNonSmi(object); | 6352 BuildCheckHeapObject(object); |
6353 HValue* context = environment()->LookupContext(); | 6353 HValue* context = environment()->LookupContext(); |
6354 instr = new(zone()) HLoadNamedFieldPolymorphic( | 6354 instr = new(zone()) HLoadNamedFieldPolymorphic( |
6355 context, object, types, name, zone()); | 6355 context, object, types, name, zone()); |
6356 } | 6356 } |
6357 | 6357 |
6358 instr->set_position(expr->position()); | 6358 instr->set_position(expr->position()); |
6359 return ast_context()->ReturnInstruction(instr, expr->id()); | 6359 return ast_context()->ReturnInstruction(instr, expr->id()); |
6360 } | 6360 } |
6361 | 6361 |
6362 | 6362 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6398 break; | 6398 break; |
6399 } else if (access.IsInobject() != new_access.IsInobject()) { | 6399 } else if (access.IsInobject() != new_access.IsInobject()) { |
6400 // In-objectness did not match. | 6400 // In-objectness did not match. |
6401 break; | 6401 break; |
6402 } | 6402 } |
6403 } | 6403 } |
6404 | 6404 |
6405 if (count != types->length()) return false; | 6405 if (count != types->length()) return false; |
6406 | 6406 |
6407 // Everything matched; can use monomorphic store. | 6407 // Everything matched; can use monomorphic store. |
6408 BuildCheckNonSmi(object); | 6408 BuildCheckHeapObject(object); |
6409 AddInstruction(HCheckMaps::New(object, types, zone())); | 6409 AddInstruction(HCheckMaps::New(object, types, zone())); |
6410 HInstruction* store; | 6410 HInstruction* store; |
6411 CHECK_ALIVE_OR_RETURN( | 6411 CHECK_ALIVE_OR_RETURN( |
6412 store = BuildStoreNamedField( | 6412 store = BuildStoreNamedField( |
6413 object, name, value, types->at(count - 1), &lookup), | 6413 object, name, value, types->at(count - 1), &lookup), |
6414 true); | 6414 true); |
6415 Push(value); | 6415 Push(value); |
6416 store->set_position(position); | 6416 store->set_position(position); |
6417 AddInstruction(store); | 6417 AddInstruction(store); |
6418 AddSimulate(assignment_id); | 6418 AddSimulate(assignment_id); |
(...skipping 18 matching lines...) Expand all Loading... |
6437 // TODO(ager): We should recognize when the prototype chains for different | 6437 // TODO(ager): We should recognize when the prototype chains for different |
6438 // maps are identical. In that case we can avoid repeatedly generating the | 6438 // maps are identical. In that case we can avoid repeatedly generating the |
6439 // same prototype map checks. | 6439 // same prototype map checks. |
6440 int count = 0; | 6440 int count = 0; |
6441 HBasicBlock* join = NULL; | 6441 HBasicBlock* join = NULL; |
6442 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 6442 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
6443 Handle<Map> map = types->at(i); | 6443 Handle<Map> map = types->at(i); |
6444 LookupResult lookup(isolate()); | 6444 LookupResult lookup(isolate()); |
6445 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 6445 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
6446 if (count == 0) { | 6446 if (count == 0) { |
6447 BuildCheckNonSmi(object); | 6447 BuildCheckHeapObject(object); |
6448 join = graph()->CreateBasicBlock(); | 6448 join = graph()->CreateBasicBlock(); |
6449 } | 6449 } |
6450 ++count; | 6450 ++count; |
6451 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 6451 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
6452 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 6452 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
6453 HCompareMap* compare = | 6453 HCompareMap* compare = |
6454 new(zone()) HCompareMap(object, map, if_true, if_false); | 6454 new(zone()) HCompareMap(object, map, if_true, if_false); |
6455 current_block()->Finish(compare); | 6455 current_block()->Finish(compare); |
6456 | 6456 |
6457 set_current_block(if_true); | 6457 set_current_block(if_true); |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7171 HValue* object, | 7171 HValue* object, |
7172 HValue* key, | 7172 HValue* key, |
7173 HValue* val, | 7173 HValue* val, |
7174 Expression* prop, | 7174 Expression* prop, |
7175 BailoutId ast_id, | 7175 BailoutId ast_id, |
7176 int position, | 7176 int position, |
7177 bool is_store, | 7177 bool is_store, |
7178 KeyedAccessStoreMode store_mode, | 7178 KeyedAccessStoreMode store_mode, |
7179 bool* has_side_effects) { | 7179 bool* has_side_effects) { |
7180 *has_side_effects = false; | 7180 *has_side_effects = false; |
7181 BuildCheckNonSmi(object); | 7181 BuildCheckHeapObject(object); |
7182 SmallMapList* maps = prop->GetReceiverTypes(); | 7182 SmallMapList* maps = prop->GetReceiverTypes(); |
7183 bool todo_external_array = false; | 7183 bool todo_external_array = false; |
7184 | 7184 |
7185 if (!is_store) { | 7185 if (!is_store) { |
7186 HInstruction* consolidated_load = | 7186 HInstruction* consolidated_load = |
7187 TryBuildConsolidatedElementLoad(object, key, val, maps); | 7187 TryBuildConsolidatedElementLoad(object, key, val, maps); |
7188 if (consolidated_load != NULL) { | 7188 if (consolidated_load != NULL) { |
7189 *has_side_effects |= consolidated_load->HasObservableSideEffects(); | 7189 *has_side_effects |= consolidated_load->HasObservableSideEffects(); |
7190 if (position != RelocInfo::kNoPosition) { | 7190 if (position != RelocInfo::kNoPosition) { |
7191 consolidated_load->set_position(position); | 7191 consolidated_load->set_position(position); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7396 bool* has_side_effects) { | 7396 bool* has_side_effects) { |
7397 ASSERT(!expr->IsPropertyName()); | 7397 ASSERT(!expr->IsPropertyName()); |
7398 HInstruction* instr = NULL; | 7398 HInstruction* instr = NULL; |
7399 if (expr->IsMonomorphic()) { | 7399 if (expr->IsMonomorphic()) { |
7400 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 7400 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
7401 if (map->has_slow_elements_kind()) { | 7401 if (map->has_slow_elements_kind()) { |
7402 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) | 7402 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) |
7403 : BuildLoadKeyedGeneric(obj, key); | 7403 : BuildLoadKeyedGeneric(obj, key); |
7404 AddInstruction(instr); | 7404 AddInstruction(instr); |
7405 } else { | 7405 } else { |
7406 BuildCheckNonSmi(obj); | 7406 BuildCheckHeapObject(obj); |
7407 instr = BuildMonomorphicElementAccess( | 7407 instr = BuildMonomorphicElementAccess( |
7408 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); | 7408 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); |
7409 } | 7409 } |
7410 } else if (expr->GetReceiverTypes() != NULL && | 7410 } else if (expr->GetReceiverTypes() != NULL && |
7411 !expr->GetReceiverTypes()->is_empty()) { | 7411 !expr->GetReceiverTypes()->is_empty()) { |
7412 return HandlePolymorphicElementAccess( | 7412 return HandlePolymorphicElementAccess( |
7413 obj, key, val, expr, ast_id, position, is_store, | 7413 obj, key, val, expr, ast_id, position, is_store, |
7414 expr->GetStoreMode(), has_side_effects); | 7414 expr->GetStoreMode(), has_side_effects); |
7415 } else { | 7415 } else { |
7416 if (is_store) { | 7416 if (is_store) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7528 ASSERT(current_block() != NULL); | 7528 ASSERT(current_block() != NULL); |
7529 ASSERT(current_block()->HasPredecessor()); | 7529 ASSERT(current_block()->HasPredecessor()); |
7530 | 7530 |
7531 if (TryArgumentsAccess(expr)) return; | 7531 if (TryArgumentsAccess(expr)) return; |
7532 | 7532 |
7533 CHECK_ALIVE(VisitForValue(expr->obj())); | 7533 CHECK_ALIVE(VisitForValue(expr->obj())); |
7534 | 7534 |
7535 HInstruction* instr = NULL; | 7535 HInstruction* instr = NULL; |
7536 if (expr->IsStringLength()) { | 7536 if (expr->IsStringLength()) { |
7537 HValue* string = Pop(); | 7537 HValue* string = Pop(); |
7538 BuildCheckNonSmi(string); | 7538 BuildCheckHeapObject(string); |
7539 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 7539 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
7540 instr = HStringLength::New(zone(), string); | 7540 instr = HStringLength::New(zone(), string); |
7541 } else if (expr->IsStringAccess()) { | 7541 } else if (expr->IsStringAccess()) { |
7542 CHECK_ALIVE(VisitForValue(expr->key())); | 7542 CHECK_ALIVE(VisitForValue(expr->key())); |
7543 HValue* index = Pop(); | 7543 HValue* index = Pop(); |
7544 HValue* string = Pop(); | 7544 HValue* string = Pop(); |
7545 HValue* context = environment()->LookupContext(); | 7545 HValue* context = environment()->LookupContext(); |
7546 HInstruction* char_code = | 7546 HInstruction* char_code = |
7547 BuildStringCharCodeAt(context, string, index); | 7547 BuildStringCharCodeAt(context, string, index); |
7548 AddInstruction(char_code); | 7548 AddInstruction(char_code); |
7549 instr = HStringCharFromCode::New(zone(), context, char_code); | 7549 instr = HStringCharFromCode::New(zone(), context, char_code); |
7550 | 7550 |
7551 } else if (expr->IsFunctionPrototype()) { | 7551 } else if (expr->IsFunctionPrototype()) { |
7552 HValue* function = Pop(); | 7552 HValue* function = Pop(); |
7553 BuildCheckNonSmi(function); | 7553 BuildCheckHeapObject(function); |
7554 instr = new(zone()) HLoadFunctionPrototype(function); | 7554 instr = new(zone()) HLoadFunctionPrototype(function); |
7555 | 7555 |
7556 } else if (expr->key()->IsPropertyName()) { | 7556 } else if (expr->key()->IsPropertyName()) { |
7557 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7557 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
7558 SmallMapList* types = expr->GetReceiverTypes(); | 7558 SmallMapList* types = expr->GetReceiverTypes(); |
7559 HValue* object = Top(); | 7559 HValue* object = Top(); |
7560 | 7560 |
7561 Handle<Map> map; | 7561 Handle<Map> map; |
7562 bool monomorphic = false; | 7562 bool monomorphic = false; |
7563 if (expr->IsMonomorphic()) { | 7563 if (expr->IsMonomorphic()) { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7717 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); | 7717 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); |
7718 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); | 7718 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); |
7719 number_block = graph()->CreateBasicBlock(); | 7719 number_block = graph()->CreateBasicBlock(); |
7720 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); | 7720 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); |
7721 smicheck->SetSuccessorAt(0, empty_smi_block); | 7721 smicheck->SetSuccessorAt(0, empty_smi_block); |
7722 smicheck->SetSuccessorAt(1, not_smi_block); | 7722 smicheck->SetSuccessorAt(1, not_smi_block); |
7723 current_block()->Finish(smicheck); | 7723 current_block()->Finish(smicheck); |
7724 empty_smi_block->Goto(number_block); | 7724 empty_smi_block->Goto(number_block); |
7725 set_current_block(not_smi_block); | 7725 set_current_block(not_smi_block); |
7726 } else { | 7726 } else { |
7727 BuildCheckNonSmi(receiver); | 7727 BuildCheckHeapObject(receiver); |
7728 } | 7728 } |
7729 } | 7729 } |
7730 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7730 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
7731 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7731 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
7732 HUnaryControlInstruction* compare; | 7732 HUnaryControlInstruction* compare; |
7733 | 7733 |
7734 if (handle_smi && map.is_identical_to(number_marker_map)) { | 7734 if (handle_smi && map.is_identical_to(number_marker_map)) { |
7735 compare = new(zone()) HCompareMap( | 7735 compare = new(zone()) HCompareMap( |
7736 receiver, heap_number_map, if_true, if_false); | 7736 receiver, heap_number_map, if_true, if_false); |
7737 map = initial_number_map; | 7737 map = initial_number_map; |
(...skipping 1590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9328 HConstant* c_index = HConstant::cast(index); | 9328 HConstant* c_index = HConstant::cast(index); |
9329 if (c_string->HasStringValue() && c_index->HasNumberValue()) { | 9329 if (c_string->HasStringValue() && c_index->HasNumberValue()) { |
9330 int32_t i = c_index->NumberValueAsInteger32(); | 9330 int32_t i = c_index->NumberValueAsInteger32(); |
9331 Handle<String> s = c_string->StringValue(); | 9331 Handle<String> s = c_string->StringValue(); |
9332 if (i < 0 || i >= s->length()) { | 9332 if (i < 0 || i >= s->length()) { |
9333 return new(zone()) HConstant(OS::nan_value()); | 9333 return new(zone()) HConstant(OS::nan_value()); |
9334 } | 9334 } |
9335 return new(zone()) HConstant(s->Get(i)); | 9335 return new(zone()) HConstant(s->Get(i)); |
9336 } | 9336 } |
9337 } | 9337 } |
9338 BuildCheckNonSmi(string); | 9338 BuildCheckHeapObject(string); |
9339 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 9339 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
9340 HInstruction* length = HStringLength::New(zone(), string); | 9340 HInstruction* length = HStringLength::New(zone(), string); |
9341 AddInstruction(length); | 9341 AddInstruction(length); |
9342 HInstruction* checked_index = AddBoundsCheck(index, length); | 9342 HInstruction* checked_index = AddBoundsCheck(index, length); |
9343 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 9343 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
9344 } | 9344 } |
9345 | 9345 |
9346 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 9346 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
9347 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 9347 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
9348 HValue* const32_minus_sa) { | 9348 HValue* const32_minus_sa) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9419 left_type = handle(Type::Any(), isolate()); | 9419 left_type = handle(Type::Any(), isolate()); |
9420 } | 9420 } |
9421 if (right_type->Is(Type::None())) { | 9421 if (right_type->Is(Type::None())) { |
9422 AddSoftDeoptimize(); | 9422 AddSoftDeoptimize(); |
9423 right_type = handle(Type::Any(), isolate()); | 9423 right_type = handle(Type::Any(), isolate()); |
9424 } | 9424 } |
9425 HInstruction* instr = NULL; | 9425 HInstruction* instr = NULL; |
9426 switch (expr->op()) { | 9426 switch (expr->op()) { |
9427 case Token::ADD: | 9427 case Token::ADD: |
9428 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { | 9428 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { |
9429 BuildCheckNonSmi(left); | 9429 BuildCheckHeapObject(left); |
9430 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 9430 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
9431 BuildCheckNonSmi(right); | 9431 BuildCheckHeapObject(right); |
9432 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 9432 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
9433 instr = HStringAdd::New(zone(), context, left, right); | 9433 instr = HStringAdd::New(zone(), context, left, right); |
9434 } else { | 9434 } else { |
9435 instr = HAdd::New(zone(), context, left, right); | 9435 instr = HAdd::New(zone(), context, left, right); |
9436 } | 9436 } |
9437 break; | 9437 break; |
9438 case Token::SUB: | 9438 case Token::SUB: |
9439 instr = HSub::New(zone(), context, left, right); | 9439 instr = HSub::New(zone(), context, left, right); |
9440 break; | 9440 break; |
9441 case Token::MUL: | 9441 case Token::MUL: |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9838 // Can we get away with map check and not instance type check? | 9838 // Can we get away with map check and not instance type check? |
9839 if (combined_type->IsClass()) { | 9839 if (combined_type->IsClass()) { |
9840 Handle<Map> map = combined_type->AsClass(); | 9840 Handle<Map> map = combined_type->AsClass(); |
9841 AddCheckMapsWithTransitions(left, map); | 9841 AddCheckMapsWithTransitions(left, map); |
9842 AddCheckMapsWithTransitions(right, map); | 9842 AddCheckMapsWithTransitions(right, map); |
9843 HCompareObjectEqAndBranch* result = | 9843 HCompareObjectEqAndBranch* result = |
9844 new(zone()) HCompareObjectEqAndBranch(left, right); | 9844 new(zone()) HCompareObjectEqAndBranch(left, right); |
9845 result->set_position(expr->position()); | 9845 result->set_position(expr->position()); |
9846 return ast_context()->ReturnControl(result, expr->id()); | 9846 return ast_context()->ReturnControl(result, expr->id()); |
9847 } else { | 9847 } else { |
9848 BuildCheckNonSmi(left); | 9848 BuildCheckHeapObject(left); |
9849 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); | 9849 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
9850 BuildCheckNonSmi(right); | 9850 BuildCheckHeapObject(right); |
9851 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); | 9851 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
9852 HCompareObjectEqAndBranch* result = | 9852 HCompareObjectEqAndBranch* result = |
9853 new(zone()) HCompareObjectEqAndBranch(left, right); | 9853 new(zone()) HCompareObjectEqAndBranch(left, right); |
9854 result->set_position(expr->position()); | 9854 result->set_position(expr->position()); |
9855 return ast_context()->ReturnControl(result, expr->id()); | 9855 return ast_context()->ReturnControl(result, expr->id()); |
9856 } | 9856 } |
9857 } | 9857 } |
9858 default: | 9858 default: |
9859 return Bailout("Unsupported non-primitive compare"); | 9859 return Bailout("Unsupported non-primitive compare"); |
9860 } | 9860 } |
9861 } else if (combined_type->Is(Type::InternalizedString()) && | 9861 } else if (combined_type->Is(Type::InternalizedString()) && |
9862 Token::IsEqualityOp(op)) { | 9862 Token::IsEqualityOp(op)) { |
9863 BuildCheckNonSmi(left); | 9863 BuildCheckHeapObject(left); |
9864 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); | 9864 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); |
9865 BuildCheckNonSmi(right); | 9865 BuildCheckHeapObject(right); |
9866 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); | 9866 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); |
9867 HCompareObjectEqAndBranch* result = | 9867 HCompareObjectEqAndBranch* result = |
9868 new(zone()) HCompareObjectEqAndBranch(left, right); | 9868 new(zone()) HCompareObjectEqAndBranch(left, right); |
9869 result->set_position(expr->position()); | 9869 result->set_position(expr->position()); |
9870 return ast_context()->ReturnControl(result, expr->id()); | 9870 return ast_context()->ReturnControl(result, expr->id()); |
9871 } else { | 9871 } else { |
9872 if (combined_rep.IsTagged() || combined_rep.IsNone()) { | 9872 if (combined_rep.IsTagged() || combined_rep.IsNone()) { |
9873 HCompareGeneric* result = | 9873 HCompareGeneric* result = |
9874 new(zone()) HCompareGeneric(context, left, right, op); | 9874 new(zone()) HCompareGeneric(context, left, right, op); |
9875 result->set_observed_input_representation(1, left_rep); | 9875 result->set_observed_input_representation(1, left_rep); |
(...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11554 if (ShouldProduceTraceOutput()) { | 11554 if (ShouldProduceTraceOutput()) { |
11555 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11555 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11556 } | 11556 } |
11557 | 11557 |
11558 #ifdef DEBUG | 11558 #ifdef DEBUG |
11559 graph_->Verify(false); // No full verify. | 11559 graph_->Verify(false); // No full verify. |
11560 #endif | 11560 #endif |
11561 } | 11561 } |
11562 | 11562 |
11563 } } // namespace v8::internal | 11563 } } // namespace v8::internal |
OLD | NEW |