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

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: address review 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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4434 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698