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 {callable} prototype. | |
jgruber
2017/06/13 07:49:52
Nit: comment needs to be updated ({callable}).
Benedikt Meurer
2017/06/13 18:22:44
Done.
| |
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(WordEqual(object_prototype, NullConstant()), &return_false); | |
jgruber
2017/06/13 07:49:52
Nit: IsNull
Benedikt Meurer
2017/06/13 18:22:44
Done.
| |
6036 GotoIf(WordEqual(object_prototype, prototype), &return_true); | |
6037 | |
6038 // Continue with the prototype. | |
6039 var_object_map.Bind(LoadMap(object_prototype)); | |
jgruber
2017/06/13 07:49:52
Please CSA_ASSERT(TaggedIsNotSmi(object_prototype)
Benedikt Meurer
2017/06/13 18:22:44
Done.
| |
6040 Goto(&loop); | |
6041 } | |
6042 | |
6043 BIND(&return_true); | |
6044 var_result.Bind(BooleanConstant(true)); | |
jgruber
2017/06/13 07:49:52
Nit: Here and other spots, FalseConstant / TrueCon
Benedikt Meurer
2017/06/13 18:22:44
Done.
| |
6045 Goto(&return_result); | |
6046 | |
6047 BIND(&return_false); | |
6048 var_result.Bind(BooleanConstant(false)); | |
6049 Goto(&return_result); | |
6050 | |
6051 BIND(&return_runtime); | |
6052 { | |
6053 // Fallback to the runtime implementation. | |
6054 var_result.Bind( | |
6055 CallRuntime(Runtime::kHasInPrototypeChain, context, object, prototype)); | |
6056 } | |
6057 Goto(&return_result); | |
6058 | |
6059 BIND(&return_result); | |
6060 return var_result.value(); | |
6061 } | |
6062 | |
6000 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, | 6063 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, |
6001 Node* object) { | 6064 Node* object) { |
6002 VARIABLE(var_result, MachineRepresentation::kTagged); | 6065 VARIABLE(var_result, MachineRepresentation::kTagged); |
6003 Label return_false(this), return_true(this), | 6066 Label return_runtime(this, Label::kDeferred), return_result(this); |
6004 return_runtime(this, Label::kDeferred), return_result(this); | |
6005 | 6067 |
6006 // Goto runtime if {object} is a Smi. | 6068 // Goto runtime if {object} is a Smi. |
6007 GotoIf(TaggedIsSmi(object), &return_runtime); | 6069 GotoIf(TaggedIsSmi(object), &return_runtime); |
6008 | 6070 |
6009 // Load map of {object}. | |
6010 Node* object_map = LoadMap(object); | |
6011 | |
6012 // Goto runtime if {callable} is a Smi. | 6071 // Goto runtime if {callable} is a Smi. |
6013 GotoIf(TaggedIsSmi(callable), &return_runtime); | 6072 GotoIf(TaggedIsSmi(callable), &return_runtime); |
6014 | 6073 |
6015 // Load map of {callable}. | 6074 // Load map of {callable}. |
6016 Node* callable_map = LoadMap(callable); | 6075 Node* callable_map = LoadMap(callable); |
6017 | 6076 |
6018 // Goto runtime if {callable} is not a JSFunction. | 6077 // Goto runtime if {callable} is not a JSFunction. |
6019 Node* callable_instance_type = LoadMapInstanceType(callable_map); | 6078 Node* callable_instance_type = LoadMapInstanceType(callable_map); |
6020 GotoIfNot( | 6079 GotoIfNot( |
6021 Word32Equal(callable_instance_type, Int32Constant(JS_FUNCTION_TYPE)), | 6080 Word32Equal(callable_instance_type, Int32Constant(JS_FUNCTION_TYPE)), |
(...skipping 27 matching lines...) Expand all Loading... | |
6049 Word32Equal(callable_prototype_instance_type, Int32Constant(MAP_TYPE)), | 6108 Word32Equal(callable_prototype_instance_type, Int32Constant(MAP_TYPE)), |
6050 &callable_prototype_valid); | 6109 &callable_prototype_valid); |
6051 var_callable_prototype.Bind( | 6110 var_callable_prototype.Bind( |
6052 LoadObjectField(callable_prototype, Map::kPrototypeOffset)); | 6111 LoadObjectField(callable_prototype, Map::kPrototypeOffset)); |
6053 Goto(&callable_prototype_valid); | 6112 Goto(&callable_prototype_valid); |
6054 BIND(&callable_prototype_valid); | 6113 BIND(&callable_prototype_valid); |
6055 callable_prototype = var_callable_prototype.value(); | 6114 callable_prototype = var_callable_prototype.value(); |
6056 } | 6115 } |
6057 | 6116 |
6058 // Loop through the prototype chain looking for the {callable} prototype. | 6117 // Loop through the prototype chain looking for the {callable} prototype. |
6059 VARIABLE(var_object_map, MachineRepresentation::kTagged, object_map); | 6118 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); | 6119 Goto(&return_result); |
6096 | 6120 |
6097 BIND(&return_runtime); | 6121 BIND(&return_runtime); |
6098 { | 6122 { |
6099 // Fallback to the runtime implementation. | 6123 // Fallback to the runtime implementation. |
6100 var_result.Bind( | 6124 var_result.Bind( |
6101 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); | 6125 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); |
6102 } | 6126 } |
6103 Goto(&return_result); | 6127 Goto(&return_result); |
6104 | 6128 |
(...skipping 3260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9365 formatted.c_str(), TENURED); | 9389 formatted.c_str(), TENURED); |
9366 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 9390 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
9367 HeapConstant(string)); | 9391 HeapConstant(string)); |
9368 } | 9392 } |
9369 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 9393 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
9370 #endif | 9394 #endif |
9371 } | 9395 } |
9372 | 9396 |
9373 } // namespace internal | 9397 } // namespace internal |
9374 } // namespace v8 | 9398 } // namespace v8 |
OLD | NEW |