| 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 11189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11200 New<HCompareObjectEqAndBranch>(left, right); | 11200 New<HCompareObjectEqAndBranch>(left, right); |
| 11201 return ast_context()->ReturnControl(result, expr->id()); | 11201 return ast_context()->ReturnControl(result, expr->id()); |
| 11202 } | 11202 } |
| 11203 | 11203 |
| 11204 if (op == Token::INSTANCEOF) { | 11204 if (op == Token::INSTANCEOF) { |
| 11205 // Check to see if the rhs of the instanceof is a known function. | 11205 // Check to see if the rhs of the instanceof is a known function. |
| 11206 if (right->IsConstant() && | 11206 if (right->IsConstant() && |
| 11207 HConstant::cast(right)->handle(isolate())->IsJSFunction()) { | 11207 HConstant::cast(right)->handle(isolate())->IsJSFunction()) { |
| 11208 Handle<JSFunction> function = | 11208 Handle<JSFunction> function = |
| 11209 Handle<JSFunction>::cast(HConstant::cast(right)->handle(isolate())); | 11209 Handle<JSFunction>::cast(HConstant::cast(right)->handle(isolate())); |
| 11210 // Make sure the prototype of {function} is the %FunctionPrototype%, and | 11210 // Make sure that the {function} already has a meaningful initial map |
| 11211 // it already has a meaningful initial map (i.e. we constructed at least | 11211 // (i.e. we constructed at least one instance using the constructor |
| 11212 // one instance using the constructor {function}). | 11212 // {function}). |
| 11213 // We can only use the fast case if @@hasInstance was not used so far. | 11213 if (function->has_initial_map()) { |
| 11214 if (function->has_initial_map() && | 11214 // Lookup @@hasInstance on the {function}. |
| 11215 function->map()->prototype() == | 11215 Handle<Map> function_map(function->map(), isolate()); |
| 11216 function->native_context()->closure() && | 11216 PropertyAccessInfo has_instance( |
| 11217 !function->map()->has_non_instance_prototype() && | 11217 this, LOAD, function_map, |
| 11218 isolate()->IsHasInstanceLookupChainIntact()) { | 11218 isolate()->factory()->has_instance_symbol()); |
| 11219 Handle<Map> initial_map(function->initial_map(), isolate()); | 11219 // Check if we are using the Function.prototype[@@hasInstance]. |
| 11220 top_info()->dependencies()->AssumeInitialMapCantChange(initial_map); | 11220 if (has_instance.CanAccessMonomorphic() && |
| 11221 top_info()->dependencies()->AssumePropertyCell( | 11221 has_instance.IsDataConstant() && |
| 11222 isolate()->factory()->has_instance_protector()); | 11222 has_instance.constant().is_identical_to( |
| 11223 HInstruction* prototype = | 11223 isolate()->function_has_instance())) { |
| 11224 Add<HConstant>(handle(initial_map->prototype(), isolate())); | 11224 // Add appropriate receiver map check and prototype chain |
| 11225 HHasInPrototypeChainAndBranch* result = | 11225 // checks to guard the @@hasInstance lookup chain. |
| 11226 New<HHasInPrototypeChainAndBranch>(left, prototype); | 11226 AddCheckMap(right, function_map); |
| 11227 return ast_context()->ReturnControl(result, expr->id()); | 11227 if (has_instance.has_holder()) { |
| 11228 Handle<JSObject> prototype( |
| 11229 JSObject::cast(has_instance.map()->prototype()), isolate()); |
| 11230 BuildCheckPrototypeMaps(prototype, has_instance.holder()); |
| 11231 } |
| 11232 // Perform the prototype chain walk. |
| 11233 Handle<Map> initial_map(function->initial_map(), isolate()); |
| 11234 top_info()->dependencies()->AssumeInitialMapCantChange(initial_map); |
| 11235 HInstruction* prototype = |
| 11236 Add<HConstant>(handle(initial_map->prototype(), isolate())); |
| 11237 HHasInPrototypeChainAndBranch* result = |
| 11238 New<HHasInPrototypeChainAndBranch>(left, prototype); |
| 11239 return ast_context()->ReturnControl(result, expr->id()); |
| 11240 } |
| 11228 } | 11241 } |
| 11229 } | 11242 } |
| 11230 | 11243 |
| 11231 Callable callable = CodeFactory::InstanceOf(isolate()); | 11244 Callable callable = CodeFactory::InstanceOf(isolate()); |
| 11232 HValue* stub = Add<HConstant>(callable.code()); | 11245 HValue* stub = Add<HConstant>(callable.code()); |
| 11233 HValue* values[] = {left, right}; | 11246 HValue* values[] = {left, right}; |
| 11234 HCallWithDescriptor* result = New<HCallWithDescriptor>( | 11247 HCallWithDescriptor* result = New<HCallWithDescriptor>( |
| 11235 stub, 0, callable.descriptor(), ArrayVector(values)); | 11248 stub, 0, callable.descriptor(), ArrayVector(values)); |
| 11236 result->set_type(HType::Boolean()); | 11249 result->set_type(HType::Boolean()); |
| 11237 return ast_context()->ReturnInstruction(result, expr->id()); | 11250 return ast_context()->ReturnInstruction(result, expr->id()); |
| (...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13010 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13023 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13011 } | 13024 } |
| 13012 | 13025 |
| 13013 #ifdef DEBUG | 13026 #ifdef DEBUG |
| 13014 graph_->Verify(false); // No full verify. | 13027 graph_->Verify(false); // No full verify. |
| 13015 #endif | 13028 #endif |
| 13016 } | 13029 } |
| 13017 | 13030 |
| 13018 } // namespace internal | 13031 } // namespace internal |
| 13019 } // namespace v8 | 13032 } // namespace v8 |
| OLD | NEW |