Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(661)

Side by Side Diff: src/hydrogen.cc

Issue 16026023: Avoid Unnecessary Smi Checks (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698