| 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 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1041 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 1042 HBasicBlock* header = graph()->CreateBasicBlock(); | 1042 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 1043 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1043 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 1044 header->SetInitialEnvironment(entry_env); | 1044 header->SetInitialEnvironment(entry_env); |
| 1045 header->AttachLoopInformation(); | 1045 header->AttachLoopInformation(); |
| 1046 return header; | 1046 return header; |
| 1047 } | 1047 } |
| 1048 | 1048 |
| 1049 | 1049 |
| 1050 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { | 1050 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { |
| 1051 if (obj->type().IsHeapObject()) return obj; |
| 1051 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); | 1052 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); |
| 1052 AddInstruction(check); | 1053 AddInstruction(check); |
| 1053 return check; | 1054 return check; |
| 1054 } | 1055 } |
| 1055 | 1056 |
| 1056 | 1057 |
| 1057 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | 1058 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
| 1058 Handle<Map> map) { | 1059 Handle<Map> map) { |
| 1059 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); | 1060 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
| 1060 AddInstruction(check); | 1061 AddInstruction(check); |
| (...skipping 5947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7008 Map* transition = lookup->GetTransitionMapFromMap(*type); | 7009 Map* transition = lookup->GetTransitionMapFromMap(*type); |
| 7009 int descriptor = transition->LastAdded(); | 7010 int descriptor = transition->LastAdded(); |
| 7010 PropertyDetails details = | 7011 PropertyDetails details = |
| 7011 transition->instance_descriptors()->GetDetails(descriptor); | 7012 transition->instance_descriptors()->GetDetails(descriptor); |
| 7012 return details.representation(); | 7013 return details.representation(); |
| 7013 } | 7014 } |
| 7014 } | 7015 } |
| 7015 | 7016 |
| 7016 | 7017 |
| 7017 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { | 7018 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { |
| 7018 AddInstruction(new(zone()) HCheckNonSmi(object)); | 7019 BuildCheckNonSmi(object); |
| 7019 AddInstruction(HCheckMaps::New(object, map, zone())); | 7020 AddInstruction(HCheckMaps::New(object, map, zone())); |
| 7020 } | 7021 } |
| 7021 | 7022 |
| 7022 | 7023 |
| 7023 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, | 7024 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
| 7024 Handle<Map> map) { | 7025 Handle<Map> map) { |
| 7025 AddInstruction(new(zone()) HCheckNonSmi(object)); | 7026 BuildCheckNonSmi(object); |
| 7026 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); | 7027 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); |
| 7027 } | 7028 } |
| 7028 | 7029 |
| 7029 | 7030 |
| 7030 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( | 7031 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
| 7031 HValue* object, | 7032 HValue* object, |
| 7032 Handle<String> name, | 7033 Handle<String> name, |
| 7033 HValue* value, | 7034 HValue* value, |
| 7034 Handle<Map> map, | 7035 Handle<Map> map, |
| 7035 LookupResult* lookup) { | 7036 LookupResult* lookup) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7160 Property* expr, | 7161 Property* expr, |
| 7161 HValue* object, | 7162 HValue* object, |
| 7162 SmallMapList* types, | 7163 SmallMapList* types, |
| 7163 Handle<String> name) { | 7164 Handle<String> name) { |
| 7164 if (!name->Equals(isolate()->heap()->length_string())) return false; | 7165 if (!name->Equals(isolate()->heap()->length_string())) return false; |
| 7165 | 7166 |
| 7166 for (int i = 0; i < types->length(); i++) { | 7167 for (int i = 0; i < types->length(); i++) { |
| 7167 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; | 7168 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; |
| 7168 } | 7169 } |
| 7169 | 7170 |
| 7170 AddInstruction(new(zone()) HCheckNonSmi(object)); | 7171 BuildCheckNonSmi(object); |
| 7171 | 7172 |
| 7172 HInstruction* typecheck = | 7173 HInstruction* typecheck = |
| 7173 AddInstruction(HCheckMaps::New(object, types, zone())); | 7174 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 7174 HInstruction* instr = | 7175 HInstruction* instr = |
| 7175 HLoadNamedField::NewArrayLength(zone(), object, typecheck); | 7176 HLoadNamedField::NewArrayLength(zone(), object, typecheck); |
| 7176 instr->set_position(expr->position()); | 7177 instr->set_position(expr->position()); |
| 7177 ast_context()->ReturnInstruction(instr, expr->id()); | 7178 ast_context()->ReturnInstruction(instr, expr->id()); |
| 7178 return true; | 7179 return true; |
| 7179 } | 7180 } |
| 7180 | 7181 |
| 7181 | 7182 |
| 7182 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | 7183 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
| 7183 HValue* object, | 7184 HValue* object, |
| 7184 SmallMapList* types, | 7185 SmallMapList* types, |
| 7185 Handle<String> name) { | 7186 Handle<String> name) { |
| 7186 | 7187 |
| 7187 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) | 7188 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) |
| 7188 return; | 7189 return; |
| 7189 | 7190 |
| 7190 AddInstruction(new(zone()) HCheckNonSmi(object)); | 7191 BuildCheckNonSmi(object); |
| 7191 | 7192 |
| 7192 // Use monomorphic load if property lookup results in the same field index | 7193 // Use monomorphic load if property lookup results in the same field index |
| 7193 // for all maps. Requires special map check on the set of all handled maps. | 7194 // for all maps. Requires special map check on the set of all handled maps. |
| 7194 HInstruction* instr = NULL; | 7195 HInstruction* instr = NULL; |
| 7195 if (types->length() > 0 && types->length() <= kMaxLoadPolymorphism) { | 7196 if (types->length() > 0 && types->length() <= kMaxLoadPolymorphism) { |
| 7196 LookupResult lookup(isolate()); | 7197 LookupResult lookup(isolate()); |
| 7197 int previous_field_offset = 0; | 7198 int previous_field_offset = 0; |
| 7198 bool previous_field_is_in_object = false; | 7199 bool previous_field_is_in_object = false; |
| 7199 Representation representation = Representation::None(); | 7200 Representation representation = Representation::None(); |
| 7200 int count; | 7201 int count; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7258 // TODO(ager): We should recognize when the prototype chains for different | 7259 // TODO(ager): We should recognize when the prototype chains for different |
| 7259 // maps are identical. In that case we can avoid repeatedly generating the | 7260 // maps are identical. In that case we can avoid repeatedly generating the |
| 7260 // same prototype map checks. | 7261 // same prototype map checks. |
| 7261 int count = 0; | 7262 int count = 0; |
| 7262 HBasicBlock* join = NULL; | 7263 HBasicBlock* join = NULL; |
| 7263 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 7264 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
| 7264 Handle<Map> map = types->at(i); | 7265 Handle<Map> map = types->at(i); |
| 7265 LookupResult lookup(isolate()); | 7266 LookupResult lookup(isolate()); |
| 7266 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 7267 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
| 7267 if (count == 0) { | 7268 if (count == 0) { |
| 7268 AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once. | 7269 BuildCheckNonSmi(object); |
| 7269 join = graph()->CreateBasicBlock(); | 7270 join = graph()->CreateBasicBlock(); |
| 7270 } | 7271 } |
| 7271 ++count; | 7272 ++count; |
| 7272 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7273 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 7273 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7274 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 7274 HCompareMap* compare = | 7275 HCompareMap* compare = |
| 7275 new(zone()) HCompareMap(object, map, if_true, if_false); | 7276 new(zone()) HCompareMap(object, map, if_true, if_false); |
| 7276 current_block()->Finish(compare); | 7277 current_block()->Finish(compare); |
| 7277 | 7278 |
| 7278 set_current_block(if_true); | 7279 set_current_block(if_true); |
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8004 HValue* object, | 8005 HValue* object, |
| 8005 HValue* key, | 8006 HValue* key, |
| 8006 HValue* val, | 8007 HValue* val, |
| 8007 Expression* prop, | 8008 Expression* prop, |
| 8008 BailoutId ast_id, | 8009 BailoutId ast_id, |
| 8009 int position, | 8010 int position, |
| 8010 bool is_store, | 8011 bool is_store, |
| 8011 KeyedAccessStoreMode store_mode, | 8012 KeyedAccessStoreMode store_mode, |
| 8012 bool* has_side_effects) { | 8013 bool* has_side_effects) { |
| 8013 *has_side_effects = false; | 8014 *has_side_effects = false; |
| 8014 AddInstruction(new(zone()) HCheckNonSmi(object)); | 8015 BuildCheckNonSmi(object); |
| 8015 SmallMapList* maps = prop->GetReceiverTypes(); | 8016 SmallMapList* maps = prop->GetReceiverTypes(); |
| 8016 bool todo_external_array = false; | 8017 bool todo_external_array = false; |
| 8017 | 8018 |
| 8018 if (!is_store) { | 8019 if (!is_store) { |
| 8019 HInstruction* consolidated_load = | 8020 HInstruction* consolidated_load = |
| 8020 TryBuildConsolidatedElementLoad(object, key, val, maps); | 8021 TryBuildConsolidatedElementLoad(object, key, val, maps); |
| 8021 if (consolidated_load != NULL) { | 8022 if (consolidated_load != NULL) { |
| 8022 *has_side_effects |= consolidated_load->HasObservableSideEffects(); | 8023 *has_side_effects |= consolidated_load->HasObservableSideEffects(); |
| 8023 if (position != RelocInfo::kNoPosition) { | 8024 if (position != RelocInfo::kNoPosition) { |
| 8024 consolidated_load->set_position(position); | 8025 consolidated_load->set_position(position); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8228 bool* has_side_effects) { | 8229 bool* has_side_effects) { |
| 8229 ASSERT(!expr->IsPropertyName()); | 8230 ASSERT(!expr->IsPropertyName()); |
| 8230 HInstruction* instr = NULL; | 8231 HInstruction* instr = NULL; |
| 8231 if (expr->IsMonomorphic()) { | 8232 if (expr->IsMonomorphic()) { |
| 8232 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 8233 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 8233 if (map->has_slow_elements_kind()) { | 8234 if (map->has_slow_elements_kind()) { |
| 8234 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) | 8235 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) |
| 8235 : BuildLoadKeyedGeneric(obj, key); | 8236 : BuildLoadKeyedGeneric(obj, key); |
| 8236 AddInstruction(instr); | 8237 AddInstruction(instr); |
| 8237 } else { | 8238 } else { |
| 8238 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 8239 BuildCheckNonSmi(obj); |
| 8239 instr = BuildMonomorphicElementAccess( | 8240 instr = BuildMonomorphicElementAccess( |
| 8240 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); | 8241 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); |
| 8241 } | 8242 } |
| 8242 } else if (expr->GetReceiverTypes() != NULL && | 8243 } else if (expr->GetReceiverTypes() != NULL && |
| 8243 !expr->GetReceiverTypes()->is_empty()) { | 8244 !expr->GetReceiverTypes()->is_empty()) { |
| 8244 return HandlePolymorphicElementAccess( | 8245 return HandlePolymorphicElementAccess( |
| 8245 obj, key, val, expr, ast_id, position, is_store, | 8246 obj, key, val, expr, ast_id, position, is_store, |
| 8246 expr->GetStoreMode(), has_side_effects); | 8247 expr->GetStoreMode(), has_side_effects); |
| 8247 } else { | 8248 } else { |
| 8248 if (is_store) { | 8249 if (is_store) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8363 ASSERT(current_block()->HasPredecessor()); | 8364 ASSERT(current_block()->HasPredecessor()); |
| 8364 expr->RecordTypeFeedback(oracle(), zone()); | 8365 expr->RecordTypeFeedback(oracle(), zone()); |
| 8365 | 8366 |
| 8366 if (TryArgumentsAccess(expr)) return; | 8367 if (TryArgumentsAccess(expr)) return; |
| 8367 | 8368 |
| 8368 CHECK_ALIVE(VisitForValue(expr->obj())); | 8369 CHECK_ALIVE(VisitForValue(expr->obj())); |
| 8369 | 8370 |
| 8370 HInstruction* instr = NULL; | 8371 HInstruction* instr = NULL; |
| 8371 if (expr->IsStringLength()) { | 8372 if (expr->IsStringLength()) { |
| 8372 HValue* string = Pop(); | 8373 HValue* string = Pop(); |
| 8373 AddInstruction(new(zone()) HCheckNonSmi(string)); | 8374 BuildCheckNonSmi(string); |
| 8374 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 8375 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 8375 instr = HStringLength::New(zone(), string); | 8376 instr = HStringLength::New(zone(), string); |
| 8376 } else if (expr->IsStringAccess()) { | 8377 } else if (expr->IsStringAccess()) { |
| 8377 CHECK_ALIVE(VisitForValue(expr->key())); | 8378 CHECK_ALIVE(VisitForValue(expr->key())); |
| 8378 HValue* index = Pop(); | 8379 HValue* index = Pop(); |
| 8379 HValue* string = Pop(); | 8380 HValue* string = Pop(); |
| 8380 HValue* context = environment()->LookupContext(); | 8381 HValue* context = environment()->LookupContext(); |
| 8381 HInstruction* char_code = | 8382 HInstruction* char_code = |
| 8382 BuildStringCharCodeAt(context, string, index); | 8383 BuildStringCharCodeAt(context, string, index); |
| 8383 AddInstruction(char_code); | 8384 AddInstruction(char_code); |
| 8384 instr = HStringCharFromCode::New(zone(), context, char_code); | 8385 instr = HStringCharFromCode::New(zone(), context, char_code); |
| 8385 | 8386 |
| 8386 } else if (expr->IsFunctionPrototype()) { | 8387 } else if (expr->IsFunctionPrototype()) { |
| 8387 HValue* function = Pop(); | 8388 HValue* function = Pop(); |
| 8388 AddInstruction(new(zone()) HCheckNonSmi(function)); | 8389 BuildCheckNonSmi(function); |
| 8389 instr = new(zone()) HLoadFunctionPrototype(function); | 8390 instr = new(zone()) HLoadFunctionPrototype(function); |
| 8390 | 8391 |
| 8391 } else if (expr->key()->IsPropertyName()) { | 8392 } else if (expr->key()->IsPropertyName()) { |
| 8392 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 8393 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 8393 SmallMapList* types = expr->GetReceiverTypes(); | 8394 SmallMapList* types = expr->GetReceiverTypes(); |
| 8394 HValue* object = Top(); | 8395 HValue* object = Top(); |
| 8395 | 8396 |
| 8396 Handle<Map> map; | 8397 Handle<Map> map; |
| 8397 bool monomorphic = false; | 8398 bool monomorphic = false; |
| 8398 if (expr->IsMonomorphic()) { | 8399 if (expr->IsMonomorphic()) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8552 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); | 8553 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); |
| 8553 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); | 8554 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); |
| 8554 number_block = graph()->CreateBasicBlock(); | 8555 number_block = graph()->CreateBasicBlock(); |
| 8555 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); | 8556 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); |
| 8556 smicheck->SetSuccessorAt(0, empty_smi_block); | 8557 smicheck->SetSuccessorAt(0, empty_smi_block); |
| 8557 smicheck->SetSuccessorAt(1, not_smi_block); | 8558 smicheck->SetSuccessorAt(1, not_smi_block); |
| 8558 current_block()->Finish(smicheck); | 8559 current_block()->Finish(smicheck); |
| 8559 empty_smi_block->Goto(number_block); | 8560 empty_smi_block->Goto(number_block); |
| 8560 set_current_block(not_smi_block); | 8561 set_current_block(not_smi_block); |
| 8561 } else { | 8562 } else { |
| 8562 AddInstruction(new(zone()) HCheckNonSmi(receiver)); | 8563 BuildCheckNonSmi(receiver); |
| 8563 } | 8564 } |
| 8564 } | 8565 } |
| 8565 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 8566 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 8566 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 8567 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 8567 HUnaryControlInstruction* compare; | 8568 HUnaryControlInstruction* compare; |
| 8568 | 8569 |
| 8569 if (handle_smi && map.is_identical_to(number_marker_map)) { | 8570 if (handle_smi && map.is_identical_to(number_marker_map)) { |
| 8570 compare = new(zone()) HCompareMap( | 8571 compare = new(zone()) HCompareMap( |
| 8571 receiver, heap_number_map, if_true, if_false); | 8572 receiver, heap_number_map, if_true, if_false); |
| 8572 map = initial_number_map; | 8573 map = initial_number_map; |
| (...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10179 HConstant* c_index = HConstant::cast(index); | 10180 HConstant* c_index = HConstant::cast(index); |
| 10180 if (c_string->HasStringValue() && c_index->HasNumberValue()) { | 10181 if (c_string->HasStringValue() && c_index->HasNumberValue()) { |
| 10181 int32_t i = c_index->NumberValueAsInteger32(); | 10182 int32_t i = c_index->NumberValueAsInteger32(); |
| 10182 Handle<String> s = c_string->StringValue(); | 10183 Handle<String> s = c_string->StringValue(); |
| 10183 if (i < 0 || i >= s->length()) { | 10184 if (i < 0 || i >= s->length()) { |
| 10184 return new(zone()) HConstant(OS::nan_value(), Representation::Double()); | 10185 return new(zone()) HConstant(OS::nan_value(), Representation::Double()); |
| 10185 } | 10186 } |
| 10186 return new(zone()) HConstant(s->Get(i), Representation::Integer32()); | 10187 return new(zone()) HConstant(s->Get(i), Representation::Integer32()); |
| 10187 } | 10188 } |
| 10188 } | 10189 } |
| 10189 AddInstruction(new(zone()) HCheckNonSmi(string)); | 10190 BuildCheckNonSmi(string); |
| 10190 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 10191 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 10191 HInstruction* length = HStringLength::New(zone(), string); | 10192 HInstruction* length = HStringLength::New(zone(), string); |
| 10192 AddInstruction(length); | 10193 AddInstruction(length); |
| 10193 HInstruction* checked_index = AddBoundsCheck(index, length); | 10194 HInstruction* checked_index = AddBoundsCheck(index, length); |
| 10194 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 10195 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 10195 } | 10196 } |
| 10196 | 10197 |
| 10197 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 10198 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
| 10198 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 10199 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
| 10199 HValue* const32_minus_sa) { | 10200 HValue* const32_minus_sa) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10265 if (left_info.IsUninitialized()) { | 10266 if (left_info.IsUninitialized()) { |
| 10266 // Can't have initialized one but not the other. | 10267 // Can't have initialized one but not the other. |
| 10267 ASSERT(right_info.IsUninitialized()); | 10268 ASSERT(right_info.IsUninitialized()); |
| 10268 AddSoftDeoptimize(); | 10269 AddSoftDeoptimize(); |
| 10269 left_info = right_info = TypeInfo::Unknown(); | 10270 left_info = right_info = TypeInfo::Unknown(); |
| 10270 } | 10271 } |
| 10271 HInstruction* instr = NULL; | 10272 HInstruction* instr = NULL; |
| 10272 switch (expr->op()) { | 10273 switch (expr->op()) { |
| 10273 case Token::ADD: | 10274 case Token::ADD: |
| 10274 if (left_info.IsString() && right_info.IsString()) { | 10275 if (left_info.IsString() && right_info.IsString()) { |
| 10275 AddInstruction(new(zone()) HCheckNonSmi(left)); | 10276 BuildCheckNonSmi(left); |
| 10276 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 10277 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
| 10277 AddInstruction(new(zone()) HCheckNonSmi(right)); | 10278 BuildCheckNonSmi(right); |
| 10278 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 10279 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
| 10279 instr = HStringAdd::New(zone(), context, left, right); | 10280 instr = HStringAdd::New(zone(), context, left, right); |
| 10280 } else { | 10281 } else { |
| 10281 instr = HAdd::New(zone(), context, left, right); | 10282 instr = HAdd::New(zone(), context, left, right); |
| 10282 } | 10283 } |
| 10283 break; | 10284 break; |
| 10284 case Token::SUB: | 10285 case Token::SUB: |
| 10285 instr = HSub::New(zone(), context, left, right); | 10286 instr = HSub::New(zone(), context, left, right); |
| 10286 break; | 10287 break; |
| 10287 case Token::MUL: | 10288 case Token::MUL: |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10673 // Can we get away with map check and not instance type check? | 10674 // Can we get away with map check and not instance type check? |
| 10674 Handle<Map> map = oracle()->GetCompareMap(expr); | 10675 Handle<Map> map = oracle()->GetCompareMap(expr); |
| 10675 if (!map.is_null()) { | 10676 if (!map.is_null()) { |
| 10676 AddCheckMapsWithTransitions(left, map); | 10677 AddCheckMapsWithTransitions(left, map); |
| 10677 AddCheckMapsWithTransitions(right, map); | 10678 AddCheckMapsWithTransitions(right, map); |
| 10678 HCompareObjectEqAndBranch* result = | 10679 HCompareObjectEqAndBranch* result = |
| 10679 new(zone()) HCompareObjectEqAndBranch(left, right); | 10680 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 10680 result->set_position(expr->position()); | 10681 result->set_position(expr->position()); |
| 10681 return ast_context()->ReturnControl(result, expr->id()); | 10682 return ast_context()->ReturnControl(result, expr->id()); |
| 10682 } else { | 10683 } else { |
| 10683 AddInstruction(new(zone()) HCheckNonSmi(left)); | 10684 BuildCheckNonSmi(left); |
| 10684 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); | 10685 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
| 10685 AddInstruction(new(zone()) HCheckNonSmi(right)); | 10686 BuildCheckNonSmi(right); |
| 10686 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); | 10687 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
| 10687 HCompareObjectEqAndBranch* result = | 10688 HCompareObjectEqAndBranch* result = |
| 10688 new(zone()) HCompareObjectEqAndBranch(left, right); | 10689 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 10689 result->set_position(expr->position()); | 10690 result->set_position(expr->position()); |
| 10690 return ast_context()->ReturnControl(result, expr->id()); | 10691 return ast_context()->ReturnControl(result, expr->id()); |
| 10691 } | 10692 } |
| 10692 } | 10693 } |
| 10693 default: | 10694 default: |
| 10694 return Bailout("Unsupported non-primitive compare"); | 10695 return Bailout("Unsupported non-primitive compare"); |
| 10695 } | 10696 } |
| 10696 } else if (overall_type_info.IsInternalizedString() && | 10697 } else if (overall_type_info.IsInternalizedString() && |
| 10697 Token::IsEqualityOp(op)) { | 10698 Token::IsEqualityOp(op)) { |
| 10698 AddInstruction(new(zone()) HCheckNonSmi(left)); | 10699 BuildCheckNonSmi(left); |
| 10699 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); | 10700 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); |
| 10700 AddInstruction(new(zone()) HCheckNonSmi(right)); | 10701 BuildCheckNonSmi(right); |
| 10701 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); | 10702 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); |
| 10702 HCompareObjectEqAndBranch* result = | 10703 HCompareObjectEqAndBranch* result = |
| 10703 new(zone()) HCompareObjectEqAndBranch(left, right); | 10704 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 10704 result->set_position(expr->position()); | 10705 result->set_position(expr->position()); |
| 10705 return ast_context()->ReturnControl(result, expr->id()); | 10706 return ast_context()->ReturnControl(result, expr->id()); |
| 10706 } else { | 10707 } else { |
| 10707 if (combined_rep.IsTagged() || combined_rep.IsNone()) { | 10708 if (combined_rep.IsTagged() || combined_rep.IsNone()) { |
| 10708 HCompareGeneric* result = | 10709 HCompareGeneric* result = |
| 10709 new(zone()) HCompareGeneric(context, left, right, op); | 10710 new(zone()) HCompareGeneric(context, left, right, op); |
| 10710 result->set_observed_input_representation(1, left_rep); | 10711 result->set_observed_input_representation(1, left_rep); |
| (...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12370 } | 12371 } |
| 12371 } | 12372 } |
| 12372 | 12373 |
| 12373 #ifdef DEBUG | 12374 #ifdef DEBUG |
| 12374 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12375 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 12375 if (allocator_ != NULL) allocator_->Verify(); | 12376 if (allocator_ != NULL) allocator_->Verify(); |
| 12376 #endif | 12377 #endif |
| 12377 } | 12378 } |
| 12378 | 12379 |
| 12379 } } // namespace v8::internal | 12380 } } // namespace v8::internal |
| OLD | NEW |