Changeset 221723 in webkit for trunk/Source/JavaScriptCore/API


Ignore:
Timestamp:
Sep 7, 2017, 1:14:30 AM (8 years ago)
Author:
Yusuke Suzuki
Message:

[JSC] Remove "malloc" and "free" from JSC/API
https://bugs.webkit.org/show_bug.cgi?id=176331

Reviewed by Keith Miller.

Remove "malloc" and "free" manual calls in JSC/API.

  • API/JSValue.mm:

(createStructHandlerMap):

  • API/JSWrapperMap.mm:

(parsePropertyAttributes):
(makeSetterName):
(copyPrototypeProperties):
Use RetainPtr<NSString> to keep NSString. We avoid repeated "char*" to "NSString" conversion.

  • API/ObjcRuntimeExtras.h:

(adoptSystem):
Add adoptSystem to automate calling system free().

(protocolImplementsProtocol):
(forEachProtocolImplementingProtocol):
(forEachMethodInClass):
(forEachMethodInProtocol):
(forEachPropertyInProtocol):
(StringRange::StringRange):
(StringRange::operator const char* const):
(StringRange::get const):
Use CString for backend.

(StructBuffer::StructBuffer):
(StructBuffer::~StructBuffer):
(StringRange::~StringRange): Deleted.
Use fastAlignedMalloc/astAlignedFree to get aligned memory.

Location:
trunk/Source/JavaScriptCore/API
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSValue.mm

    r211247 r221723  
    10551055        char idType[3];
    10561056        // Check 2nd argument type is "@"
    1057         char* secondType = method_copyArgumentType(method, 3);
    1058         if (strcmp(secondType, "@") != 0) {
    1059             free(secondType);
    1060             return;
     1057        {
     1058            auto secondType = adoptSystem<char[]>(method_copyArgumentType(method, 3));
     1059            if (strcmp(secondType.get(), "@") != 0)
     1060                return;
    10611061        }
    1062         free(secondType);
    10631062        // Check result type is also "@"
    10641063        method_getReturnType(method, idType, 3);
    10651064        if (strcmp(idType, "@") != 0)
    10661065            return;
    1067         char* type = method_copyArgumentType(method, 2);
    1068         structHandlers->add(StringImpl::create(type), (StructTagHandler){ selector, 0 });
    1069         free(type);
     1066        {
     1067            auto type = adoptSystem<char[]>(method_copyArgumentType(method, 2));
     1068            structHandlers->add(StringImpl::create(type.get()), (StructTagHandler) { selector, 0 });
     1069        }
    10701070    });
    10711071
     
    10821082            return;
    10831083        // Try to find a matching valueWith<Foo>:context: method.
    1084         char* type = method_copyReturnType(method);
    1085 
    1086         StructHandlers::iterator iter = structHandlers->find(type);
    1087         free(type);
     1084        auto type = adoptSystem<char[]>(method_copyReturnType(method));
     1085        StructHandlers::iterator iter = structHandlers->find(type.get());
    10881086        if (iter == structHandlers->end())
    10891087            return;
  • trunk/Source/JavaScriptCore/API/JSWrapperMap.mm

    r221583 r221723  
    9292        // Copy the character, converting to upper case if necessary.
    9393        // If the character we copy is '\0', then we're done!
    94         if (!(*(output++) = toupper(c)))
     94        if (!(*(output++) = toASCIIUpper(c)))
    9595            goto done;
    9696        // Loop over characters other than ':'.
     
    261261}
    262262
    263 static bool parsePropertyAttributes(objc_property_t property, char*& getterName, char*& setterName)
     263struct Property {
     264    const char* name;
     265    RetainPtr<NSString> getterName;
     266    RetainPtr<NSString> setterName;
     267};
     268
     269static bool parsePropertyAttributes(objc_property_t objcProperty, Property& property)
    264270{
    265271    bool readonly = false;
    266272    unsigned attributeCount;
    267     objc_property_attribute_t* attributes = property_copyAttributeList(property, &attributeCount);
     273    auto attributes = adoptSystem<objc_property_attribute_t[]>(property_copyAttributeList(objcProperty, &attributeCount));
    268274    if (attributeCount) {
    269275        for (unsigned i = 0; i < attributeCount; ++i) {
    270276            switch (*(attributes[i].name)) {
    271277            case 'G':
    272                 getterName = strdup(attributes[i].value);
     278                property.getterName = @(attributes[i].value);
    273279                break;
    274280            case 'S':
    275                 setterName = strdup(attributes[i].value);
     281                property.setterName = @(attributes[i].value);
    276282                break;
    277283            case 'R':
     
    282288            }
    283289        }
    284         free(attributes);
    285290    }
    286291    return readonly;
    287292}
    288293
    289 static char* makeSetterName(const char* name)
     294static RetainPtr<NSString> makeSetterName(const char* name)
    290295{
    291296    size_t nameLength = strlen(name);
    292     char* setterName = (char*)malloc(nameLength + 5); // "set" Name ":\0"
    293     setterName[0] = 's';
    294     setterName[1] = 'e';
    295     setterName[2] = 't';
    296     setterName[3] = toupper(*name);
    297     memcpy(setterName + 4, name + 1, nameLength - 1);
    298     setterName[nameLength + 3] = ':';
    299     setterName[nameLength + 4] = '\0';
    300     return setterName;
     297    // "set" Name ":\0"  => nameLength + 5.
     298    Vector<char, 128> buffer(nameLength + 5);
     299    buffer[0] = 's';
     300    buffer[1] = 'e';
     301    buffer[2] = 't';
     302    buffer[3] = toASCIIUpper(*name);
     303    memcpy(buffer.data() + 4, name + 1, nameLength - 1);
     304    buffer[nameLength + 3] = ':';
     305    buffer[nameLength + 4] = '\0';
     306    return @(buffer.data());
    301307}
    302308
     
    304310{
    305311    // First gather propreties into this list, then handle the methods (capturing the accessor methods).
    306     struct Property {
    307         const char* name;
    308         char* getterName;
    309         char* setterName;
    310     };
    311312    __block Vector<Property> propertyList;
    312313
     
    317318    JSValue *undefined = [JSValue valueWithUndefinedInContext:context];
    318319
    319     forEachPropertyInProtocol(protocol, ^(objc_property_t property){
    320         char* getterName = 0;
    321         char* setterName = 0;
    322         bool readonly = parsePropertyAttributes(property, getterName, setterName);
    323         const char* name = property_getName(property);
    324 
    325         // Add the names of the getter & setter methods to
    326         if (!getterName)
    327             getterName = strdup(name);
    328         accessorMethods[@(getterName)] = undefined;
     320    forEachPropertyInProtocol(protocol, ^(objc_property_t objcProperty) {
     321        const char* name = property_getName(objcProperty);
     322        Property property { name, nullptr, nullptr };
     323        bool readonly = parsePropertyAttributes(objcProperty, property);
     324
     325        // Add the names of the getter & setter methods to
     326        if (!property.getterName)
     327            property.getterName = @(name);
     328        accessorMethods[property.getterName.get()] = undefined;
    329329        if (!readonly) {
    330             if (!setterName)
    331                 setterName = makeSetterName(name);
    332             accessorMethods[@(setterName)] = undefined;
     330            if (!property.setterName)
     331                property.setterName = makeSetterName(name);
     332            accessorMethods[property.setterName.get()] = undefined;
    333333        }
    334334
    335335        // Add the properties to a list.
    336         propertyList.append((Property){ name, getterName, setterName });
     336        propertyList.append(WTFMove(property));
    337337    });
    338338
     
    341341
    342342    // Iterate the propertyList & generate accessor properties.
    343     for (size_t i = 0; i < propertyList.size(); ++i) {
    344         Property& property = propertyList[i];
    345 
    346         JSValue *getter = accessorMethods[@(property.getterName)];
    347         free(property.getterName);
     343    for (auto& property : propertyList) {
     344        JSValue* getter = accessorMethods[property.getterName.get()];
    348345        ASSERT(![getter isUndefined]);
    349346
    350         JSValue *setter = undefined;
     347        JSValue* setter = undefined;
    351348        if (property.setterName) {
    352             setter = accessorMethods[@(property.setterName)];
    353             free(property.setterName);
     349            setter = accessorMethods[property.setterName.get()];
    354350            ASSERT(![setter isUndefined]);
    355351        }
  • trunk/Source/JavaScriptCore/API/ObjcRuntimeExtras.h

    r218316 r221723  
    2424 */
    2525
     26#import <memory>
    2627#import <objc/Protocol.h>
    2728#import <objc/runtime.h>
    2829#import <wtf/HashSet.h>
     30#import <wtf/SystemFree.h>
    2931#import <wtf/Vector.h>
     32#import <wtf/text/CString.h>
     33
     34template<typename T, typename U>
     35inline std::unique_ptr<T, WTF::SystemFree<T>> adoptSystem(U value)
     36{
     37    return std::unique_ptr<T, WTF::SystemFree<T>>(value);
     38}
    3039
    3140inline bool protocolImplementsProtocol(Protocol *candidate, Protocol *target)
    3241{
    3342    unsigned protocolProtocolsCount;
    34     Protocol ** protocolProtocols = protocol_copyProtocolList(candidate, &protocolProtocolsCount);
     43    auto protocolProtocols = adoptSystem<Protocol*[]>(protocol_copyProtocolList(candidate, &protocolProtocolsCount));
    3544    for (unsigned i = 0; i < protocolProtocolsCount; ++i) {
    36         if (protocol_isEqual(protocolProtocols[i], target)) {
    37             free(protocolProtocols);
     45        if (protocol_isEqual(protocolProtocols[i], target))
    3846            return true;
    39         }
    40     }
    41     free(protocolProtocols);
     47    }
    4248    return false;
    4349}
     
    4854    ASSERT(target);
    4955
    50     Vector<Protocol *> worklist;
     56    Vector<Protocol*> worklist;
    5157    HashSet<void*> visited;
    5258
    5359    // Initially fill the worklist with the Class's protocols.
    54     unsigned protocolsCount;
    55     Protocol ** protocols = class_copyProtocolList(cls, &protocolsCount);
    56     worklist.append(protocols, protocolsCount);
    57     free(protocols);
     60    {
     61        unsigned protocolsCount;
     62        auto protocols = adoptSystem<Protocol*[]>(class_copyProtocolList(cls, &protocolsCount));
     63        worklist.append(protocols.get(), protocolsCount);
     64    }
    5865
    5966    bool stop = false;
     
    7481
    7582        // Add incorporated protocols to the worklist.
    76         protocols = protocol_copyProtocolList(protocol, &protocolsCount);
    77         worklist.append(protocols, protocolsCount);
    78         free(protocols);
     83        {
     84            unsigned protocolsCount;
     85            auto protocols = adoptSystem<Protocol*[]>(protocol_copyProtocolList(protocol, &protocolsCount));
     86            worklist.append(protocols.get(), protocolsCount);
     87        }
    7988    }
    8089}
     
    8392{
    8493    unsigned count;
    85     Method* methods = class_copyMethodList(cls, &count);
     94    auto methods = adoptSystem<Method[]>(class_copyMethodList(cls, &count));
    8695    for (unsigned i = 0; i < count; ++i)
    8796        callback(methods[i]);
    88     free(methods);
    8997}
    9098
     
    92100{
    93101    unsigned count;
    94     struct objc_method_description* methods = protocol_copyMethodDescriptionList(protocol, isRequiredMethod, isInstanceMethod, &count);
     102    auto methods = adoptSystem<objc_method_description[]>(protocol_copyMethodDescriptionList(protocol, isRequiredMethod, isInstanceMethod, &count));
    95103    for (unsigned i = 0; i < count; ++i)
    96104        callback(methods[i].name, methods[i].types);
    97     free(methods);
    98105}
    99106
     
    101108{
    102109    unsigned count;
    103     objc_property_t* properties = protocol_copyPropertyList(protocol, &count);
     110    auto properties = adoptSystem<objc_property_t[]>(protocol_copyPropertyList(protocol, &count));
    104111    for (unsigned i = 0; i < count; ++i)
    105112        callback(properties[i]);
    106     free(properties);
    107113}
    108114
     
    125131    WTF_MAKE_NONCOPYABLE(StringRange);
    126132public:
    127     StringRange(const char* begin, const char* end) : m_ptr(strndup(begin, end - begin)) { }
    128     ~StringRange() { free(m_ptr); }
    129     operator const char*() const { return m_ptr; }
    130     const char* get() const { return m_ptr; }
     133    StringRange(const char* begin, const char* end)
     134        : m_string(begin, end - begin)
     135    { }
     136    operator const char*() const { return m_string.data(); }
     137    const char* get() const { return m_string.data(); }
    131138
    132139private:
    133     char* m_ptr;
     140    CString m_string;
    134141};
    135142
     
    141148        NSUInteger size, alignment;
    142149        NSGetSizeAndAlignment(encodedType, &size, &alignment);
    143         --alignment;
    144         m_allocation = static_cast<char*>(malloc(size + alignment));
    145         m_buffer = reinterpret_cast<char*>((reinterpret_cast<intptr_t>(m_allocation) + alignment) & ~alignment);
    146     }
    147 
    148     ~StructBuffer() { free(m_allocation); }
     150        m_buffer = fastAlignedMalloc(alignment, size);
     151    }
     152
     153    ~StructBuffer() { fastAlignedFree(m_buffer); }
    149154    operator void*() const { return m_buffer; }
    150155
    151156private:
    152     void* m_allocation;
    153157    void* m_buffer;
    154158};
Note: See TracChangeset for help on using the changeset viewer.