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 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 8692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8703 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 8703 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
8704 &if_istypedarray, &if_isgeneric); | 8704 &if_istypedarray, &if_isgeneric); |
8705 | 8705 |
8706 Bind(&if_isgeneric); | 8706 Bind(&if_isgeneric); |
8707 { | 8707 { |
8708 Label if_isfast(this), if_isslow(this); | 8708 Label if_isfast(this), if_isslow(this); |
8709 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 8709 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); |
8710 | 8710 |
8711 Bind(&if_isfast); | 8711 Bind(&if_isfast); |
8712 { | 8712 { |
8713 Node* map_index = | 8713 Label if_ispacked(this), if_isholey(this); |
8714 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | 8714 Node* elements_kind = LoadMapElementsKind(array_map); |
8715 LoadMapElementsKind(array_map)); | 8715 Branch(Word32Equal(Word32And(elements_kind, Int32Constant(1)), |
8716 CSA_ASSERT(IntPtrGreaterThanOrEqual( | 8716 Int32Constant(0)), |
8717 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); | 8717 &if_ispacked, &if_isholey); |
Camillo Bruni
2016/11/09 12:03:49
Could you add a IsFastPackedElementsKind helper on
caitp
2016/11/09 17:40:16
Done, 2 new helpers (CSA::IsFastElementsKind() and
| |
8718 CSA_ASSERT(IntPtrLessThan( | 8718 Bind(&if_isholey); |
8719 map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset))); | 8719 { |
8720 // Check the protector cell --- create a Generic iterator if invalid | |
8721 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); | |
8722 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); | |
8723 GotoUnless( | |
8724 WordEqual( | |
8725 LoadObjectField(protector_cell, PropertyCell::kValueOffset), | |
8726 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), | |
8727 &if_isslow); | |
8720 | 8728 |
8721 var_map_index.Bind(map_index); | 8729 // Otherwise, check that the prototype is a stable initial |
Benedikt Meurer
2016/11/09 05:37:05
Maybe it'd be sufficient to check for current cont
caitp
2016/11/09 17:40:16
Updated to only check the current context, and add
| |
8722 var_array_map.Bind(array_map); | 8730 // Array prototype |
8723 Goto(&allocate_iterator); | 8731 Node* prototype = LoadMapPrototype(array_map); |
8732 GotoUnless(IsAnyInitialArrayPrototype(prototype), &if_isslow); | |
8733 GotoUnless(Word32Equal(DecodeWord32<Map::IsUnstable>( | |
8734 LoadMapBitField3(array_map)), | |
8735 Int32Constant(0)), | |
8736 &if_isslow); | |
8737 | |
8738 // Check that the Object prototype is stable as well. | |
8739 prototype = LoadMapPrototype(LoadMap(prototype)); | |
Camillo Bruni
2016/11/09 12:03:49
object_map = LoadMap(prototype); ...
| |
8740 GotoUnless(IsAnyInitialObjectPrototype(prototype), &if_isslow); | |
8741 Branch(Word32Equal( | |
8742 DecodeWord32<Map::IsUnstable>(LoadMapBitField3(array_map)), | |
Camillo Bruni
2016/11/09 12:03:49
You probably wanted to check the object_map here.
caitp
2016/11/09 17:40:16
good catch, but I guess we don't need stability ch
| |
8743 Int32Constant(0)), | |
8744 &if_ispacked, &if_isslow); | |
8745 } | |
8746 Bind(&if_ispacked); | |
8747 { | |
8748 Node* map_index = | |
8749 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | |
8750 LoadMapElementsKind(array_map)); | |
8751 CSA_ASSERT(IntPtrGreaterThanOrEqual( | |
8752 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); | |
8753 CSA_ASSERT(IntPtrLessThan( | |
8754 map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset))); | |
8755 | |
8756 var_map_index.Bind(map_index); | |
8757 var_array_map.Bind(array_map); | |
8758 Goto(&allocate_iterator); | |
8759 } | |
8724 } | 8760 } |
8725 | 8761 |
8726 Bind(&if_isslow); | 8762 Bind(&if_isslow); |
8727 { | 8763 { |
8728 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), | 8764 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), |
8729 IntPtrConstant(kSlowIteratorOffset)); | 8765 IntPtrConstant(kSlowIteratorOffset)); |
8730 var_map_index.Bind(map_index); | 8766 var_map_index.Bind(map_index); |
8731 var_array_map.Bind(UndefinedConstant()); | 8767 var_array_map.Bind(UndefinedConstant()); |
8732 Goto(&allocate_iterator); | 8768 Goto(&allocate_iterator); |
8733 } | 8769 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8853 }, | 8889 }, |
8854 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); | 8890 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); |
8855 } | 8891 } |
8856 | 8892 |
8857 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 8893 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
8858 assembler_->PopAndReturn( | 8894 assembler_->PopAndReturn( |
8859 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 8895 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
8860 value); | 8896 value); |
8861 } | 8897 } |
8862 | 8898 |
8899 // Implement Isolate::IsInAnyContext() in CodeStubAssembler form. | |
8900 compiler::Node* CodeStubAssembler::IsInAnyNativeContext(compiler::Node* object, | |
8901 uint32_t index) { | |
8902 Variable var_context(this, MachineRepresentation::kTagged); | |
8903 Variable var_found(this, MachineRepresentation::kWord32); | |
8904 var_context.Bind(LoadFirstNativeContext()); | |
8905 var_found.Bind(Int32Constant(0)); | |
8906 | |
8907 Label loop(this, &var_context), done(this); | |
8908 Branch(WordEqual(var_context.value(), UndefinedConstant()), &done, &loop); | |
Camillo Bruni
2016/11/09 12:03:49
nit: IsUndefined(var_context.value())
| |
8909 | |
8910 // Loop while {context} is not undefined: | |
8911 Bind(&loop); | |
8912 { | |
8913 Label continue_loop(this), break_loop(this); | |
8914 Node* context = var_context.value(); | |
8915 Node* value = LoadContextElement(context, index); | |
8916 | |
8917 Branch(WordEqual(value, object), &break_loop, &continue_loop); | |
8918 Bind(&break_loop); | |
8919 var_found.Bind(Int32Constant(1)); | |
8920 Goto(&done); | |
8921 | |
8922 Bind(&continue_loop); | |
8923 var_context.Bind(LoadContextElement(context, Context::NEXT_CONTEXT_LINK)); | |
8924 Branch(WordEqual(var_context.value(), UndefinedConstant()), &done, &loop); | |
Camillo Bruni
2016/11/09 12:03:49
nit: IsUndefined(var_context.value())
| |
8925 } | |
8926 | |
8927 Bind(&done); | |
8928 Node* result = Word32NotEqual(var_found.value(), Int32Constant(0)); | |
8929 return result; | |
8930 } | |
8931 | |
8932 compiler::Node* CodeStubAssembler::IsAnyInitialArrayPrototype( | |
8933 compiler::Node* object) { | |
8934 return IsInAnyNativeContext(object, Context::INITIAL_ARRAY_PROTOTYPE_INDEX); | |
8935 } | |
8936 | |
8937 compiler::Node* CodeStubAssembler::IsAnyInitialObjectPrototype( | |
8938 compiler::Node* object) { | |
8939 return IsInAnyNativeContext(object, Context::INITIAL_OBJECT_PROTOTYPE_INDEX); | |
8940 } | |
8941 | |
8863 } // namespace internal | 8942 } // namespace internal |
8864 } // namespace v8 | 8943 } // namespace v8 |
OLD | NEW |