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 |