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 |