| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 6052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6063 if (lookup_.IsFound()) return LoadResult(map); | 6063 if (lookup_.IsFound()) return LoadResult(map); |
| 6064 } | 6064 } |
| 6065 lookup_.NotFound(); | 6065 lookup_.NotFound(); |
| 6066 return true; | 6066 return true; |
| 6067 } | 6067 } |
| 6068 | 6068 |
| 6069 | 6069 |
| 6070 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { | 6070 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { |
| 6071 if (!CanInlinePropertyAccess(type_)) return false; | 6071 if (!CanInlinePropertyAccess(type_)) return false; |
| 6072 if (IsJSObjectFieldAccessor()) return IsLoad(); | 6072 if (IsJSObjectFieldAccessor()) return IsLoad(); |
| 6073 if (this->map()->function_with_prototype() && |
| 6074 !this->map()->has_non_instance_prototype() && |
| 6075 name_.is_identical_to(isolate()->factory()->prototype_string())) { |
| 6076 return IsLoad(); |
| 6077 } |
| 6073 if (!LookupDescriptor()) return false; | 6078 if (!LookupDescriptor()) return false; |
| 6074 if (lookup_.IsFound()) { | 6079 if (lookup_.IsFound()) { |
| 6075 if (IsLoad()) return true; | 6080 if (IsLoad()) return true; |
| 6076 return !lookup_.IsReadOnly() && lookup_.IsCacheable(); | 6081 return !lookup_.IsReadOnly() && lookup_.IsCacheable(); |
| 6077 } | 6082 } |
| 6078 if (!LookupInPrototypes()) return false; | 6083 if (!LookupInPrototypes()) return false; |
| 6079 if (IsLoad()) return true; | 6084 if (IsLoad()) return true; |
| 6080 | 6085 |
| 6081 if (lookup_.IsPropertyCallbacks()) return true; | 6086 if (lookup_.IsPropertyCallbacks()) return true; |
| 6082 Handle<Map> map = this->map(); | 6087 Handle<Map> map = this->map(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6154 BailoutId ast_id, | 6159 BailoutId ast_id, |
| 6155 BailoutId return_id, | 6160 BailoutId return_id, |
| 6156 bool can_inline_accessor) { | 6161 bool can_inline_accessor) { |
| 6157 | 6162 |
| 6158 HObjectAccess access = HObjectAccess::ForMap(); // bogus default | 6163 HObjectAccess access = HObjectAccess::ForMap(); // bogus default |
| 6159 if (info->GetJSObjectFieldAccess(&access)) { | 6164 if (info->GetJSObjectFieldAccess(&access)) { |
| 6160 ASSERT(info->IsLoad()); | 6165 ASSERT(info->IsLoad()); |
| 6161 return New<HLoadNamedField>(object, checked_object, access); | 6166 return New<HLoadNamedField>(object, checked_object, access); |
| 6162 } | 6167 } |
| 6163 | 6168 |
| 6169 if (info->name().is_identical_to(isolate()->factory()->prototype_string()) && |
| 6170 info->map()->function_with_prototype()) { |
| 6171 ASSERT(!info->map()->has_non_instance_prototype()); |
| 6172 return New<HLoadFunctionPrototype>(checked_object); |
| 6173 } |
| 6174 |
| 6164 HValue* checked_holder = checked_object; | 6175 HValue* checked_holder = checked_object; |
| 6165 if (info->has_holder()) { | 6176 if (info->has_holder()) { |
| 6166 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); | 6177 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); |
| 6167 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); | 6178 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); |
| 6168 } | 6179 } |
| 6169 | 6180 |
| 6170 if (!info->lookup()->IsFound()) { | 6181 if (!info->lookup()->IsFound()) { |
| 6171 ASSERT(info->IsLoad()); | 6182 ASSERT(info->IsLoad()); |
| 6172 return graph()->GetConstantUndefined(); | 6183 return graph()->GetConstantUndefined(); |
| 6173 } | 6184 } |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6568 | 6579 |
| 6569 case Variable::LOOKUP: | 6580 case Variable::LOOKUP: |
| 6570 return Bailout(kCompoundAssignmentToLookupSlot); | 6581 return Bailout(kCompoundAssignmentToLookupSlot); |
| 6571 } | 6582 } |
| 6572 return ast_context()->ReturnValue(Pop()); | 6583 return ast_context()->ReturnValue(Pop()); |
| 6573 | 6584 |
| 6574 } else if (prop != NULL) { | 6585 } else if (prop != NULL) { |
| 6575 CHECK_ALIVE(VisitForValue(prop->obj())); | 6586 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 6576 HValue* object = Top(); | 6587 HValue* object = Top(); |
| 6577 HValue* key = NULL; | 6588 HValue* key = NULL; |
| 6578 if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) || | 6589 if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) { |
| 6579 prop->IsStringAccess()) { | |
| 6580 CHECK_ALIVE(VisitForValue(prop->key())); | 6590 CHECK_ALIVE(VisitForValue(prop->key())); |
| 6581 key = Top(); | 6591 key = Top(); |
| 6582 } | 6592 } |
| 6583 | 6593 |
| 6584 CHECK_ALIVE(PushLoad(prop, object, key)); | 6594 CHECK_ALIVE(PushLoad(prop, object, key)); |
| 6585 | 6595 |
| 6586 CHECK_ALIVE(VisitForValue(expr->value())); | 6596 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6587 HValue* right = Pop(); | 6597 HValue* right = Pop(); |
| 6588 HValue* left = Pop(); | 6598 HValue* left = Pop(); |
| 6589 | 6599 |
| (...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7279 void HOptimizedGraphBuilder::BuildLoad(Property* expr, | 7289 void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
| 7280 BailoutId ast_id) { | 7290 BailoutId ast_id) { |
| 7281 HInstruction* instr = NULL; | 7291 HInstruction* instr = NULL; |
| 7282 if (expr->IsStringAccess()) { | 7292 if (expr->IsStringAccess()) { |
| 7283 HValue* index = Pop(); | 7293 HValue* index = Pop(); |
| 7284 HValue* string = Pop(); | 7294 HValue* string = Pop(); |
| 7285 HInstruction* char_code = BuildStringCharCodeAt(string, index); | 7295 HInstruction* char_code = BuildStringCharCodeAt(string, index); |
| 7286 AddInstruction(char_code); | 7296 AddInstruction(char_code); |
| 7287 instr = NewUncasted<HStringCharFromCode>(char_code); | 7297 instr = NewUncasted<HStringCharFromCode>(char_code); |
| 7288 | 7298 |
| 7289 } else if (expr->IsFunctionPrototype()) { | |
| 7290 HValue* function = Pop(); | |
| 7291 BuildCheckHeapObject(function); | |
| 7292 instr = New<HLoadFunctionPrototype>(function); | |
| 7293 | |
| 7294 } else if (expr->key()->IsPropertyName()) { | 7299 } else if (expr->key()->IsPropertyName()) { |
| 7295 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7300 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 7296 HValue* object = Pop(); | 7301 HValue* object = Pop(); |
| 7297 | 7302 |
| 7298 instr = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, | 7303 instr = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, |
| 7299 object, name, NULL, expr->IsUninitialized()); | 7304 object, name, NULL, expr->IsUninitialized()); |
| 7300 if (instr == NULL) return; | 7305 if (instr == NULL) return; |
| 7301 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); | 7306 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); |
| 7302 | 7307 |
| 7303 } else { | 7308 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 7323 | 7328 |
| 7324 | 7329 |
| 7325 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7330 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
| 7326 ASSERT(!HasStackOverflow()); | 7331 ASSERT(!HasStackOverflow()); |
| 7327 ASSERT(current_block() != NULL); | 7332 ASSERT(current_block() != NULL); |
| 7328 ASSERT(current_block()->HasPredecessor()); | 7333 ASSERT(current_block()->HasPredecessor()); |
| 7329 | 7334 |
| 7330 if (TryArgumentsAccess(expr)) return; | 7335 if (TryArgumentsAccess(expr)) return; |
| 7331 | 7336 |
| 7332 CHECK_ALIVE(VisitForValue(expr->obj())); | 7337 CHECK_ALIVE(VisitForValue(expr->obj())); |
| 7333 if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) || | 7338 if (!expr->key()->IsPropertyName() || expr->IsStringAccess()) { |
| 7334 expr->IsStringAccess()) { | |
| 7335 CHECK_ALIVE(VisitForValue(expr->key())); | 7339 CHECK_ALIVE(VisitForValue(expr->key())); |
| 7336 } | 7340 } |
| 7337 | 7341 |
| 7338 BuildLoad(expr, expr->id()); | 7342 BuildLoad(expr, expr->id()); |
| 7339 } | 7343 } |
| 7340 | 7344 |
| 7341 | 7345 |
| 7342 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) { | 7346 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) { |
| 7343 HCheckMaps* check = Add<HCheckMaps>( | 7347 HCheckMaps* check = Add<HCheckMaps>( |
| 7344 Add<HConstant>(constant), handle(constant->map())); | 7348 Add<HConstant>(constant), handle(constant->map())); |
| (...skipping 2673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10018 } | 10022 } |
| 10019 | 10023 |
| 10020 // Argument of the count operation is a property. | 10024 // Argument of the count operation is a property. |
| 10021 ASSERT(prop != NULL); | 10025 ASSERT(prop != NULL); |
| 10022 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 10026 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
| 10023 | 10027 |
| 10024 CHECK_ALIVE(VisitForValue(prop->obj())); | 10028 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 10025 HValue* object = Top(); | 10029 HValue* object = Top(); |
| 10026 | 10030 |
| 10027 HValue* key = NULL; | 10031 HValue* key = NULL; |
| 10028 if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) || | 10032 if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) { |
| 10029 prop->IsStringAccess()) { | |
| 10030 CHECK_ALIVE(VisitForValue(prop->key())); | 10033 CHECK_ALIVE(VisitForValue(prop->key())); |
| 10031 key = Top(); | 10034 key = Top(); |
| 10032 } | 10035 } |
| 10033 | 10036 |
| 10034 CHECK_ALIVE(PushLoad(prop, object, key)); | 10037 CHECK_ALIVE(PushLoad(prop, object, key)); |
| 10035 | 10038 |
| 10036 after = BuildIncrement(returns_original_input, expr); | 10039 after = BuildIncrement(returns_original_input, expr); |
| 10037 | 10040 |
| 10038 if (returns_original_input) { | 10041 if (returns_original_input) { |
| 10039 input = Pop(); | 10042 input = Pop(); |
| (...skipping 2430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12470 if (ShouldProduceTraceOutput()) { | 12473 if (ShouldProduceTraceOutput()) { |
| 12471 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12474 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12472 } | 12475 } |
| 12473 | 12476 |
| 12474 #ifdef DEBUG | 12477 #ifdef DEBUG |
| 12475 graph_->Verify(false); // No full verify. | 12478 graph_->Verify(false); // No full verify. |
| 12476 #endif | 12479 #endif |
| 12477 } | 12480 } |
| 12478 | 12481 |
| 12479 } } // namespace v8::internal | 12482 } } // namespace v8::internal |
| OLD | NEW |