LCOV - code coverage report
Current view: top level - js/src/jit - TypedObjectPrediction.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 109 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "jit/TypedObjectPrediction.h"
       8             : 
       9             : using namespace js;
      10             : using namespace jit;
      11             : 
      12             : static const size_t ALL_FIELDS = SIZE_MAX;
      13             : 
      14             : // Sets the prediction to be the common prefix of descrA and descrB,
      15             : // considering at most the first max fields.
      16             : //
      17             : // In the case where the current prediction is a specific struct,
      18             : // and we are now seeing a second struct, then descrA and descrB will be
      19             : // the current and new struct and max will be ALL_FIELDS.
      20             : //
      21             : // In the case where the current prediction is already a prefix, and
      22             : // we are now seeing an additional struct, then descrA will be the
      23             : // current struct and max will be the current prefix length, and
      24             : // descrB will be the new struct.
      25             : //
      26             : // (Note that in general it is not important which struct is passed as
      27             : // descrA and which struct is passed as descrB, as the operation is
      28             : // symmetric.)
      29             : void
      30           0 : TypedObjectPrediction::markAsCommonPrefix(const StructTypeDescr& descrA,
      31             :                                           const StructTypeDescr& descrB,
      32             :                                           size_t max)
      33             : {
      34             :     // count is the number of fields in common. It begins as the min
      35             :     // of the number of fields from descrA, descrB, and max, and then
      36             :     // is decremented as we find uncommon fields.
      37           0 :     if (max > descrA.fieldCount())
      38           0 :         max = descrA.fieldCount();
      39           0 :     if (max > descrB.fieldCount())
      40           0 :         max = descrB.fieldCount();
      41             : 
      42           0 :     size_t i = 0;
      43           0 :     for (; i < max; i++) {
      44           0 :         if (&descrA.fieldName(i) != &descrB.fieldName(i))
      45           0 :             break;
      46           0 :         if (&descrA.fieldDescr(i) != &descrB.fieldDescr(i))
      47           0 :             break;
      48           0 :         MOZ_ASSERT(descrA.fieldOffset(i) == descrB.fieldOffset(i));
      49             :     }
      50             : 
      51           0 :     if (i == 0) {
      52             :         // empty prefix is not particularly useful.
      53           0 :         markInconsistent();
      54             :     } else {
      55           0 :         setPrefix(descrA, i);
      56             :     }
      57           0 : }
      58             : 
      59             : void
      60           0 : TypedObjectPrediction::addDescr(const TypeDescr& descr)
      61             : {
      62           0 :     switch (predictionKind()) {
      63             :       case Empty:
      64           0 :         return setDescr(descr);
      65             : 
      66             :       case Inconsistent:
      67           0 :         return; // keep same state
      68             : 
      69             :       case Descr: {
      70           0 :         if (&descr == data_.descr)
      71           0 :             return; // keep same state
      72             : 
      73           0 :         if (descr.kind() != data_.descr->kind())
      74           0 :             return markInconsistent();
      75             : 
      76           0 :         if (descr.kind() != type::Struct)
      77           0 :             return markInconsistent();
      78             : 
      79           0 :         const StructTypeDescr& structDescr = descr.as<StructTypeDescr>();
      80           0 :         const StructTypeDescr& currentDescr = data_.descr->as<StructTypeDescr>();
      81           0 :         markAsCommonPrefix(structDescr, currentDescr, ALL_FIELDS);
      82           0 :         return;
      83             :       }
      84             : 
      85             :       case Prefix:
      86           0 :         if (descr.kind() != type::Struct)
      87           0 :             return markInconsistent();
      88             : 
      89           0 :         markAsCommonPrefix(*data_.prefix.descr,
      90             :                            descr.as<StructTypeDescr>(),
      91           0 :                            data_.prefix.fields);
      92           0 :         return;
      93             :     }
      94             : 
      95           0 :     MOZ_CRASH("Bad predictionKind");
      96             : }
      97             : 
      98             : type::Kind
      99           0 : TypedObjectPrediction::kind() const
     100             : {
     101           0 :     switch (predictionKind()) {
     102             :       case TypedObjectPrediction::Empty:
     103             :       case TypedObjectPrediction::Inconsistent:
     104           0 :         break;
     105             : 
     106             :       case TypedObjectPrediction::Descr:
     107           0 :         return descr().kind();
     108             : 
     109             :       case TypedObjectPrediction::Prefix:
     110           0 :         return prefix().descr->kind();
     111             :     }
     112             : 
     113           0 :     MOZ_CRASH("Bad prediction kind");
     114             : }
     115             : 
     116             : bool
     117           0 : TypedObjectPrediction::ofArrayKind() const
     118             : {
     119           0 :     switch (kind()) {
     120             :       case type::Scalar:
     121             :       case type::Reference:
     122             :       case type::Simd:
     123             :       case type::Struct:
     124           0 :         return false;
     125             : 
     126             :       case type::Array:
     127           0 :         return true;
     128             :     }
     129             : 
     130           0 :     MOZ_CRASH("Bad kind");
     131             : }
     132             : 
     133             : bool
     134           0 : TypedObjectPrediction::hasKnownSize(uint32_t* out) const
     135             : {
     136           0 :     switch (predictionKind()) {
     137             :       case TypedObjectPrediction::Empty:
     138             :       case TypedObjectPrediction::Inconsistent:
     139           0 :         return false;
     140             : 
     141             :       case TypedObjectPrediction::Descr:
     142           0 :         *out = descr().size();
     143           0 :         return true;
     144             : 
     145             :       case TypedObjectPrediction::Prefix:
     146             :         // We only know a prefix of the struct fields, hence we do not
     147             :         // know its complete size.
     148           0 :         return false;
     149             : 
     150             :       default:
     151           0 :         MOZ_CRASH("Bad prediction kind");
     152             :     }
     153             : }
     154             : 
     155             : const TypedProto*
     156           0 : TypedObjectPrediction::getKnownPrototype() const
     157             : {
     158           0 :     switch (predictionKind()) {
     159             :       case TypedObjectPrediction::Empty:
     160             :       case TypedObjectPrediction::Inconsistent:
     161           0 :         return nullptr;
     162             : 
     163             :       case TypedObjectPrediction::Descr:
     164           0 :         if (descr().is<ComplexTypeDescr>())
     165           0 :             return &descr().as<ComplexTypeDescr>().instancePrototype();
     166           0 :         return nullptr;
     167             : 
     168             :       case TypedObjectPrediction::Prefix:
     169             :         // We only know a prefix of the struct fields, hence we cannot
     170             :         // say for certain what its prototype will be.
     171           0 :         return nullptr;
     172             : 
     173             :       default:
     174           0 :         MOZ_CRASH("Bad prediction kind");
     175             :     }
     176             : }
     177             : 
     178             : template<typename T>
     179             : typename T::Type
     180           0 : TypedObjectPrediction::extractType() const
     181             : {
     182           0 :     MOZ_ASSERT(kind() == T::Kind);
     183           0 :     switch (predictionKind()) {
     184             :       case TypedObjectPrediction::Empty:
     185             :       case TypedObjectPrediction::Inconsistent:
     186           0 :         break;
     187             : 
     188             :       case TypedObjectPrediction::Descr:
     189           0 :         return descr().as<T>().type();
     190             : 
     191             :       case TypedObjectPrediction::Prefix:
     192           0 :         break; // Prefixes are always structs, never scalars etc
     193             :     }
     194             : 
     195           0 :     MOZ_CRASH("Bad prediction kind");
     196             : }
     197             : 
     198             : ScalarTypeDescr::Type
     199           0 : TypedObjectPrediction::scalarType() const
     200             : {
     201           0 :     return extractType<ScalarTypeDescr>();
     202             : }
     203             : 
     204             : ReferenceTypeDescr::Type
     205           0 : TypedObjectPrediction::referenceType() const
     206             : {
     207           0 :     return extractType<ReferenceTypeDescr>();
     208             : }
     209             : 
     210             : SimdType
     211           0 : TypedObjectPrediction::simdType() const
     212             : {
     213           0 :     return descr().as<SimdTypeDescr>().type();
     214             : }
     215             : 
     216             : bool
     217           0 : TypedObjectPrediction::hasKnownArrayLength(int32_t* length) const
     218             : {
     219           0 :     switch (predictionKind()) {
     220             :       case TypedObjectPrediction::Empty:
     221             :       case TypedObjectPrediction::Inconsistent:
     222           0 :         return false;
     223             : 
     224             :       case TypedObjectPrediction::Descr:
     225             :         // In later patches, this condition will always be true
     226             :         // so long as this represents an array
     227           0 :         if (descr().is<ArrayTypeDescr>()) {
     228           0 :             *length = descr().as<ArrayTypeDescr>().length();
     229           0 :             return true;
     230             :         }
     231           0 :         return false;
     232             : 
     233             :       case TypedObjectPrediction::Prefix:
     234             :         // Prefixes are always structs, never arrays
     235           0 :         return false;
     236             : 
     237             :       default:
     238           0 :         MOZ_CRASH("Bad prediction kind");
     239             :     }
     240             : }
     241             : 
     242             : TypedObjectPrediction
     243           0 : TypedObjectPrediction::arrayElementType() const
     244             : {
     245           0 :     MOZ_ASSERT(ofArrayKind());
     246           0 :     switch (predictionKind()) {
     247             :       case TypedObjectPrediction::Empty:
     248             :       case TypedObjectPrediction::Inconsistent:
     249           0 :         break;
     250             : 
     251             :       case TypedObjectPrediction::Descr:
     252           0 :         return TypedObjectPrediction(descr().as<ArrayTypeDescr>().elementType());
     253             : 
     254             :       case TypedObjectPrediction::Prefix:
     255           0 :         break; // Prefixes are always structs, never arrays
     256             :     }
     257           0 :     MOZ_CRASH("Bad prediction kind");
     258             : }
     259             : 
     260             : bool
     261           0 : TypedObjectPrediction::hasFieldNamedPrefix(const StructTypeDescr& descr,
     262             :                                            size_t fieldCount,
     263             :                                            jsid id,
     264             :                                            size_t* fieldOffset,
     265             :                                            TypedObjectPrediction* out,
     266             :                                            size_t* index) const
     267             : {
     268             :     // Find the index of the field |id| if any.
     269           0 :     if (!descr.fieldIndex(id, index))
     270           0 :         return false;
     271             : 
     272             :     // Check whether the index falls within our known safe prefix.
     273           0 :     if (*index >= fieldCount)
     274           0 :         return false;
     275             : 
     276             :     // Load the offset and type.
     277           0 :     *fieldOffset = descr.fieldOffset(*index);
     278           0 :     *out = TypedObjectPrediction(descr.fieldDescr(*index));
     279           0 :     return true;
     280             : }
     281             : 
     282             : bool
     283           0 : TypedObjectPrediction::hasFieldNamed(jsid id,
     284             :                                      size_t* fieldOffset,
     285             :                                      TypedObjectPrediction* fieldType,
     286             :                                      size_t* fieldIndex) const
     287             : {
     288           0 :     MOZ_ASSERT(kind() == type::Struct);
     289             : 
     290           0 :     switch (predictionKind()) {
     291             :       case TypedObjectPrediction::Empty:
     292             :       case TypedObjectPrediction::Inconsistent:
     293           0 :         return false;
     294             : 
     295             :       case TypedObjectPrediction::Descr:
     296           0 :         return hasFieldNamedPrefix(
     297           0 :             descr().as<StructTypeDescr>(), ALL_FIELDS,
     298           0 :             id, fieldOffset, fieldType, fieldIndex);
     299             : 
     300             :       case TypedObjectPrediction::Prefix:
     301             :         return hasFieldNamedPrefix(
     302           0 :             *prefix().descr, prefix().fields,
     303           0 :             id, fieldOffset, fieldType, fieldIndex);
     304             : 
     305             :       default:
     306           0 :         MOZ_CRASH("Bad prediction kind");
     307             :     }
     308             : }

Generated by: LCOV version 1.13