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 |