| 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 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 | 13 |
| 14 using compiler::Node; | 14 using compiler::Node; |
| 15 | 15 |
| 16 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, | 16 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, |
| 17 const CallInterfaceDescriptor& descriptor, | 17 const CallInterfaceDescriptor& descriptor, |
| 18 Code::Flags flags, const char* name, | 18 Code::Flags flags, const char* name, |
| 19 size_t result_size) | 19 size_t result_size) |
| 20 : compiler::CodeAssembler(isolate, zone, descriptor, flags, name, | 20 : compiler::CodeAssembler(isolate, zone, descriptor, flags, name, |
| 21 result_size) {} | 21 result_size) {} |
| 22 | 22 |
| 23 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, | 23 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, |
| 24 int parameter_count, Code::Flags flags, | 24 int parameter_count, Code::Flags flags, |
| 25 const char* name) | 25 const char* name) |
| 26 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} | 26 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} |
| 27 | 27 |
| 28 void CodeStubAssembler::Assert(Node* condition, const char* message, | 28 void CodeStubAssembler::Assert(ConditionBody codition_body, const char* message, |
| 29 const char* file, int line) { | 29 const char* file, int line) { |
| 30 #if defined(DEBUG) | 30 #if defined(DEBUG) |
| 31 Label ok(this); | 31 Label ok(this); |
| 32 Label not_ok(this, Label::kDeferred); | 32 Label not_ok(this, Label::kDeferred); |
| 33 if (message != nullptr && FLAG_code_comments) { | 33 if (message != nullptr && FLAG_code_comments) { |
| 34 Comment("[ Assert: %s", message); | 34 Comment("[ Assert: %s", message); |
| 35 } else { | 35 } else { |
| 36 Comment("[ Assert "); | 36 Comment("[ Assert"); |
| 37 } | 37 } |
| 38 | 38 Node* condition = codition_body(); |
| 39 DCHECK_NOT_NULL(condition); |
| 39 Branch(condition, &ok, ¬_ok); | 40 Branch(condition, &ok, ¬_ok); |
| 40 Bind(¬_ok); | 41 Bind(¬_ok); |
| 41 if (message != nullptr) { | 42 if (message != nullptr) { |
| 42 char chars[1024]; | 43 char chars[1024]; |
| 43 Vector<char> buffer(chars); | 44 Vector<char> buffer(chars); |
| 44 if (file != nullptr) { | 45 if (file != nullptr) { |
| 45 SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line); | 46 SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line); |
| 46 } else { | 47 } else { |
| 47 SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message); | 48 SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message); |
| 48 } | 49 } |
| 49 CallRuntime( | 50 CallRuntime( |
| 50 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), | 51 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), |
| 51 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); | 52 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); |
| 52 } | 53 } |
| 53 DebugBreak(); | 54 DebugBreak(); |
| 54 Goto(&ok); | 55 Goto(&ok); |
| 55 Bind(&ok); | 56 Bind(&ok); |
| 56 Comment("] Assert"); | 57 Comment("] Assert"); |
| 57 #endif | 58 #endif |
| 58 } | 59 } |
| 59 | 60 |
| 61 void CodeStubAssembler::SlowAssert(ConditionBody codition_body, |
| 62 const char* message, const char* file, |
| 63 int line) { |
| 64 #ifdef ENABLE_SLOW_DCHECKS |
| 65 if (FLAG_enable_slow_asserts) { |
| 66 Assert(codition_body, message, file, line); |
| 67 } |
| 68 #endif |
| 69 } |
| 70 |
| 60 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } | 71 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } |
| 61 | 72 |
| 62 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ | 73 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ |
| 63 Node* CodeStubAssembler::name##Constant() { \ | 74 Node* CodeStubAssembler::name##Constant() { \ |
| 64 return LoadRoot(Heap::k##rootName##RootIndex); \ | 75 return LoadRoot(Heap::k##rootName##RootIndex); \ |
| 65 } | 76 } |
| 66 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR); | 77 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR); |
| 67 #undef HEAP_CONSTANT_ACCESSOR | 78 #undef HEAP_CONSTANT_ACCESSOR |
| 68 | 79 |
| 69 #define HEAP_CONSTANT_TEST(rootName, name) \ | 80 #define HEAP_CONSTANT_TEST(rootName, name) \ |
| (...skipping 1553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 Bind(&done); | 1634 Bind(&done); |
| 1624 | 1635 |
| 1625 return result.value(); | 1636 return result.value(); |
| 1626 } | 1637 } |
| 1627 | 1638 |
| 1628 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, | 1639 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, |
| 1629 Node* index, Node* input) { | 1640 Node* index, Node* input) { |
| 1630 Node* const max_length = | 1641 Node* const max_length = |
| 1631 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); | 1642 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); |
| 1632 CSA_ASSERT(SmiLessThanOrEqual(length, max_length)); | 1643 CSA_ASSERT(SmiLessThanOrEqual(length, max_length)); |
| 1644 USE(max_length); |
| 1633 | 1645 |
| 1634 // Allocate the JSRegExpResult. | 1646 // Allocate the JSRegExpResult. |
| 1635 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove | 1647 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove |
| 1636 // unneeded store of elements. | 1648 // unneeded store of elements. |
| 1637 Node* const result = Allocate(JSRegExpResult::kSize); | 1649 Node* const result = Allocate(JSRegExpResult::kSize); |
| 1638 | 1650 |
| 1639 // TODO(jgruber): Store map as Heap constant? | 1651 // TODO(jgruber): Store map as Heap constant? |
| 1640 Node* const native_context = LoadNativeContext(context); | 1652 Node* const native_context = LoadNativeContext(context); |
| 1641 Node* const map = | 1653 Node* const map = |
| 1642 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); | 1654 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); |
| (...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2636 value); | 2648 value); |
| 2637 var_value_map.Bind(UndefinedConstant()); | 2649 var_value_map.Bind(UndefinedConstant()); |
| 2638 Goto(&out); // Never reached. | 2650 Goto(&out); // Never reached. |
| 2639 | 2651 |
| 2640 Bind(&out); | 2652 Bind(&out); |
| 2641 return var_value_map.value(); | 2653 return var_value_map.value(); |
| 2642 } | 2654 } |
| 2643 | 2655 |
| 2644 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { | 2656 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { |
| 2645 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 2657 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
| 2646 Node* bit_field = LoadMapBitField(map); | |
| 2647 uint32_t mask = | 2658 uint32_t mask = |
| 2648 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; | 2659 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
| 2660 USE(mask); |
| 2649 // Interceptors or access checks imply special receiver. | 2661 // Interceptors or access checks imply special receiver. |
| 2650 CSA_ASSERT( | 2662 CSA_ASSERT(Select(IsSetWord32(LoadMapBitField(map), mask), is_special, |
| 2651 Select(IsSetWord32(bit_field, mask), is_special, Int32Constant(1))); | 2663 Int32Constant(1), MachineRepresentation::kWord32)); |
| 2652 return is_special; | 2664 return is_special; |
| 2653 } | 2665 } |
| 2654 | 2666 |
| 2655 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { | 2667 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { |
| 2656 CSA_SLOW_ASSERT(IsMap(map)); | 2668 CSA_SLOW_ASSERT(IsMap(map)); |
| 2657 Node* bit_field3 = LoadMapBitField3(map); | 2669 Node* bit_field3 = LoadMapBitField3(map); |
| 2658 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), | 2670 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), |
| 2659 Int32Constant(0)); | 2671 Int32Constant(0)); |
| 2660 } | 2672 } |
| 2661 | 2673 |
| (...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4208 Label* if_bailout) { | 4220 Label* if_bailout) { |
| 4209 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); | 4221 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); |
| 4210 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 4222 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
| 4211 | 4223 |
| 4212 Label if_objectisspecial(this); | 4224 Label if_objectisspecial(this); |
| 4213 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 4225 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
| 4214 GotoIf(Int32LessThanOrEqual(instance_type, | 4226 GotoIf(Int32LessThanOrEqual(instance_type, |
| 4215 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), | 4227 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), |
| 4216 &if_objectisspecial); | 4228 &if_objectisspecial); |
| 4217 | 4229 |
| 4218 Node* bit_field = LoadMapBitField(map); | 4230 uint32_t mask = |
| 4219 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | | 4231 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
| 4220 1 << Map::kIsAccessCheckNeeded); | 4232 CSA_ASSERT(Word32BinaryNot(IsSetWord32(LoadMapBitField(map), mask))); |
| 4221 CSA_ASSERT(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 4233 USE(mask); |
| 4222 | 4234 |
| 4223 Node* bit_field3 = LoadMapBitField3(map); | 4235 Node* bit_field3 = LoadMapBitField3(map); |
| 4224 Label if_isfastmap(this), if_isslowmap(this); | 4236 Label if_isfastmap(this), if_isslowmap(this); |
| 4225 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap, | 4237 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap, |
| 4226 &if_isfastmap); | 4238 &if_isfastmap); |
| 4227 Bind(&if_isfastmap); | 4239 Bind(&if_isfastmap); |
| 4228 { | 4240 { |
| 4229 Comment("DescriptorArrayLookup"); | 4241 Comment("DescriptorArrayLookup"); |
| 4230 Node* nof = | 4242 Node* nof = |
| 4231 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3); | 4243 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3); |
| (...skipping 4608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8840 } | 8852 } |
| 8841 | 8853 |
| 8842 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 8854 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
| 8843 assembler_->PopAndReturn( | 8855 assembler_->PopAndReturn( |
| 8844 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 8856 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
| 8845 value); | 8857 value); |
| 8846 } | 8858 } |
| 8847 | 8859 |
| 8848 } // namespace internal | 8860 } // namespace internal |
| 8849 } // namespace v8 | 8861 } // namespace v8 |
| OLD | NEW |