OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 5979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5990 Node* instance_type = LoadMapInstanceType(map); | 5990 Node* instance_type = LoadMapInstanceType(map); |
5991 | 5991 |
5992 var_holder.Bind(proto); | 5992 var_holder.Bind(proto); |
5993 var_holder_map.Bind(map); | 5993 var_holder_map.Bind(map); |
5994 var_holder_instance_type.Bind(instance_type); | 5994 var_holder_instance_type.Bind(instance_type); |
5995 Goto(&loop); | 5995 Goto(&loop); |
5996 } | 5996 } |
5997 } | 5997 } |
5998 } | 5998 } |
5999 | 5999 |
| 6000 Node* CodeStubAssembler::HasInPrototypeChain(Node* context, Node* object, |
| 6001 Node* prototype) { |
| 6002 CSA_ASSERT(this, TaggedIsNotSmi(object)); |
| 6003 VARIABLE(var_result, MachineRepresentation::kTagged); |
| 6004 Label return_false(this), return_true(this), |
| 6005 return_runtime(this, Label::kDeferred), return_result(this); |
| 6006 |
| 6007 // Loop through the prototype chain looking for the {prototype}. |
| 6008 VARIABLE(var_object_map, MachineRepresentation::kTagged, LoadMap(object)); |
| 6009 Label loop(this, &var_object_map); |
| 6010 Goto(&loop); |
| 6011 BIND(&loop); |
| 6012 { |
| 6013 // Check if we can determine the prototype directly from the {object_map}. |
| 6014 Label if_objectisdirect(this), if_objectisspecial(this, Label::kDeferred); |
| 6015 Node* object_map = var_object_map.value(); |
| 6016 Node* object_instance_type = LoadMapInstanceType(object_map); |
| 6017 Branch(IsSpecialReceiverInstanceType(object_instance_type), |
| 6018 &if_objectisspecial, &if_objectisdirect); |
| 6019 BIND(&if_objectisspecial); |
| 6020 { |
| 6021 // The {object_map} is a special receiver map or a primitive map, check |
| 6022 // if we need to use the if_objectisspecial path in the runtime. |
| 6023 GotoIf(InstanceTypeEqual(object_instance_type, JS_PROXY_TYPE), |
| 6024 &return_runtime); |
| 6025 Node* object_bitfield = LoadMapBitField(object_map); |
| 6026 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | |
| 6027 1 << Map::kIsAccessCheckNeeded); |
| 6028 Branch(Word32NotEqual(Word32And(object_bitfield, mask), Int32Constant(0)), |
| 6029 &return_runtime, &if_objectisdirect); |
| 6030 } |
| 6031 BIND(&if_objectisdirect); |
| 6032 |
| 6033 // Check the current {object} prototype. |
| 6034 Node* object_prototype = LoadMapPrototype(object_map); |
| 6035 GotoIf(IsNull(object_prototype), &return_false); |
| 6036 GotoIf(WordEqual(object_prototype, prototype), &return_true); |
| 6037 |
| 6038 // Continue with the prototype. |
| 6039 CSA_ASSERT(this, TaggedIsNotSmi(object_prototype)); |
| 6040 var_object_map.Bind(LoadMap(object_prototype)); |
| 6041 Goto(&loop); |
| 6042 } |
| 6043 |
| 6044 BIND(&return_true); |
| 6045 var_result.Bind(TrueConstant()); |
| 6046 Goto(&return_result); |
| 6047 |
| 6048 BIND(&return_false); |
| 6049 var_result.Bind(FalseConstant()); |
| 6050 Goto(&return_result); |
| 6051 |
| 6052 BIND(&return_runtime); |
| 6053 { |
| 6054 // Fallback to the runtime implementation. |
| 6055 var_result.Bind( |
| 6056 CallRuntime(Runtime::kHasInPrototypeChain, context, object, prototype)); |
| 6057 } |
| 6058 Goto(&return_result); |
| 6059 |
| 6060 BIND(&return_result); |
| 6061 return var_result.value(); |
| 6062 } |
| 6063 |
6000 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, | 6064 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, |
6001 Node* object) { | 6065 Node* object) { |
6002 VARIABLE(var_result, MachineRepresentation::kTagged); | 6066 VARIABLE(var_result, MachineRepresentation::kTagged); |
6003 Label return_false(this), return_true(this), | 6067 Label return_runtime(this, Label::kDeferred), return_result(this); |
6004 return_runtime(this, Label::kDeferred), return_result(this); | |
6005 | 6068 |
6006 // Goto runtime if {object} is a Smi. | 6069 // Goto runtime if {object} is a Smi. |
6007 GotoIf(TaggedIsSmi(object), &return_runtime); | 6070 GotoIf(TaggedIsSmi(object), &return_runtime); |
6008 | 6071 |
6009 // Load map of {object}. | |
6010 Node* object_map = LoadMap(object); | |
6011 | |
6012 // Goto runtime if {callable} is a Smi. | 6072 // Goto runtime if {callable} is a Smi. |
6013 GotoIf(TaggedIsSmi(callable), &return_runtime); | 6073 GotoIf(TaggedIsSmi(callable), &return_runtime); |
6014 | 6074 |
6015 // Load map of {callable}. | 6075 // Load map of {callable}. |
6016 Node* callable_map = LoadMap(callable); | 6076 Node* callable_map = LoadMap(callable); |
6017 | 6077 |
6018 // Goto runtime if {callable} is not a JSFunction. | 6078 // Goto runtime if {callable} is not a JSFunction. |
6019 Node* callable_instance_type = LoadMapInstanceType(callable_map); | 6079 Node* callable_instance_type = LoadMapInstanceType(callable_map); |
6020 GotoIfNot( | 6080 GotoIfNot( |
6021 Word32Equal(callable_instance_type, Int32Constant(JS_FUNCTION_TYPE)), | 6081 Word32Equal(callable_instance_type, Int32Constant(JS_FUNCTION_TYPE)), |
(...skipping 27 matching lines...) Expand all Loading... |
6049 Word32Equal(callable_prototype_instance_type, Int32Constant(MAP_TYPE)), | 6109 Word32Equal(callable_prototype_instance_type, Int32Constant(MAP_TYPE)), |
6050 &callable_prototype_valid); | 6110 &callable_prototype_valid); |
6051 var_callable_prototype.Bind( | 6111 var_callable_prototype.Bind( |
6052 LoadObjectField(callable_prototype, Map::kPrototypeOffset)); | 6112 LoadObjectField(callable_prototype, Map::kPrototypeOffset)); |
6053 Goto(&callable_prototype_valid); | 6113 Goto(&callable_prototype_valid); |
6054 BIND(&callable_prototype_valid); | 6114 BIND(&callable_prototype_valid); |
6055 callable_prototype = var_callable_prototype.value(); | 6115 callable_prototype = var_callable_prototype.value(); |
6056 } | 6116 } |
6057 | 6117 |
6058 // Loop through the prototype chain looking for the {callable} prototype. | 6118 // Loop through the prototype chain looking for the {callable} prototype. |
6059 VARIABLE(var_object_map, MachineRepresentation::kTagged, object_map); | 6119 var_result.Bind(HasInPrototypeChain(context, object, callable_prototype)); |
6060 Label loop(this, &var_object_map); | |
6061 Goto(&loop); | |
6062 BIND(&loop); | |
6063 { | |
6064 Node* object_map = var_object_map.value(); | |
6065 | |
6066 // Check if the current {object} needs to be access checked. | |
6067 Node* object_bitfield = LoadMapBitField(object_map); | |
6068 GotoIfNot( | |
6069 Word32Equal(Word32And(object_bitfield, | |
6070 Int32Constant(1 << Map::kIsAccessCheckNeeded)), | |
6071 Int32Constant(0)), | |
6072 &return_runtime); | |
6073 | |
6074 // Check if the current {object} is a proxy. | |
6075 Node* object_instance_type = LoadMapInstanceType(object_map); | |
6076 GotoIf(Word32Equal(object_instance_type, Int32Constant(JS_PROXY_TYPE)), | |
6077 &return_runtime); | |
6078 | |
6079 // Check the current {object} prototype. | |
6080 Node* object_prototype = LoadMapPrototype(object_map); | |
6081 GotoIf(WordEqual(object_prototype, NullConstant()), &return_false); | |
6082 GotoIf(WordEqual(object_prototype, callable_prototype), &return_true); | |
6083 | |
6084 // Continue with the prototype. | |
6085 var_object_map.Bind(LoadMap(object_prototype)); | |
6086 Goto(&loop); | |
6087 } | |
6088 | |
6089 BIND(&return_true); | |
6090 var_result.Bind(BooleanConstant(true)); | |
6091 Goto(&return_result); | |
6092 | |
6093 BIND(&return_false); | |
6094 var_result.Bind(BooleanConstant(false)); | |
6095 Goto(&return_result); | 6120 Goto(&return_result); |
6096 | 6121 |
6097 BIND(&return_runtime); | 6122 BIND(&return_runtime); |
6098 { | 6123 { |
6099 // Fallback to the runtime implementation. | 6124 // Fallback to the runtime implementation. |
6100 var_result.Bind( | 6125 var_result.Bind( |
6101 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); | 6126 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); |
6102 } | 6127 } |
6103 Goto(&return_result); | 6128 Goto(&return_result); |
6104 | 6129 |
(...skipping 3260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9365 formatted.c_str(), TENURED); | 9390 formatted.c_str(), TENURED); |
9366 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 9391 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
9367 HeapConstant(string)); | 9392 HeapConstant(string)); |
9368 } | 9393 } |
9369 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 9394 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
9370 #endif | 9395 #endif |
9371 } | 9396 } |
9372 | 9397 |
9373 } // namespace internal | 9398 } // namespace internal |
9374 } // namespace v8 | 9399 } // namespace v8 |
OLD | NEW |