Changeset 230143 in webkit


Ignore:
Timestamp:
Apr 1, 2018 10:08:39 AM (6 years ago)
Author:
fpizlo@apple.com
Message:

JSC crash in JIT code with for-of loop and Array/Set iterators
https://bugs.webkit.org/show_bug.cgi?id=183174

Reviewed by Saam Barati.

JSTests:

  • microbenchmarks/hoist-get-by-offset-tower-with-inferred-types.js: Added. This test shows that fixing the bug didn't break hoisting of GetByOffset with inferred types. I confirmed that if I did break it, this test slows down by >7x.

(foo):

  • stress/hoist-get-by-offset-with-control-dependent-inferred-type.js: Added. This test shows that the bug is fixed.

(f):

Source/JavaScriptCore:

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute): Fix the bug by making GetByOffset and friends verify that they are getting the type proof they want at the desired hoisting site.

Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r230119 r230143  
     12018-03-31  Filip Pizlo  <fpizlo@apple.com>
     2
     3        JSC crash in JIT code with for-of loop and Array/Set iterators
     4        https://bugs.webkit.org/show_bug.cgi?id=183174
     5
     6        Reviewed by Saam Barati.
     7
     8        * microbenchmarks/hoist-get-by-offset-tower-with-inferred-types.js: Added. This test shows that fixing the bug didn't break hoisting of GetByOffset with inferred types. I confirmed that if I did break it, this test slows down by >7x.
     9        (foo):
     10        * stress/hoist-get-by-offset-with-control-dependent-inferred-type.js: Added. This test shows that the bug is fixed.
     11        (f):
     12
    1132018-03-30  JF Bastien  <jfbastien@apple.com>
    214
  • trunk/Source/JavaScriptCore/ChangeLog

    r230130 r230143  
     12018-03-31  Filip Pizlo  <fpizlo@apple.com>
     2
     3        JSC crash in JIT code with for-of loop and Array/Set iterators
     4        https://bugs.webkit.org/show_bug.cgi?id=183174
     5
     6        Reviewed by Saam Barati.
     7
     8        * dfg/DFGSafeToExecute.h:
     9        (JSC::DFG::safeToExecute): Fix the bug by making GetByOffset and friends verify that they are getting the type proof they want at the desired hoisting site.
     10
    1112018-03-30  Filip Pizlo  <fpizlo@apple.com>
    212
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r229514 r230143  
    11/*
    2  * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    505505    case GetGetterSetterByOffset:
    506506    case PutByOffset: {
    507         PropertyOffset offset = node->storageAccessData().offset;
    508 
    509         if (state.structureClobberState() == StructuresAreWatched) {
     507        StorageAccessData& data = node->storageAccessData();
     508        PropertyOffset offset = data.offset;
     509        UniquedStringImpl* uid = graph.identifiers()[data.identifierNumber];
     510
     511        InferredType::Descriptor inferredType;
     512        switch (node->op()) {
     513        case GetByOffset:
     514        case GetGetterSetterByOffset:
     515            inferredType = data.inferredType;
     516            break;
     517        case PutByOffset:
     518            // PutByOffset knows about inferred types because it's the enforcer of that type rather
     519            // than the consumer of that type. Therefore, PutByOffset expects TOP for the purpose of
     520            // safe-to-execute in the sense that it will be happy with anything as general as TOP
     521            // (so any type).
     522            inferredType = InferredType::Top;
     523            break;
     524        default:
     525            DFG_CRASH(graph, node, "Bad opcode");
     526            break;
     527        }
     528
     529        // Graph::isSafeToLoad() is all about proofs derived from PropertyConditions. Those don't
     530        // know anything about inferred types. But if we have a proof derived from watching a
     531        // structure that has a type proof, then the next case below will deal with it.
     532        if (state.structureClobberState() == StructuresAreWatched
     533            && inferredType.kind() == InferredType::Top) {
    510534            if (JSObject* knownBase = node->child1()->dynamicCastConstant<JSObject*>(graph.m_vm)) {
    511535                if (graph.isSafeToLoad(knownBase, offset))
     
    518542            return false;
    519543        for (unsigned i = value.size(); i--;) {
    520             if (!value[i]->isValidOffset(offset))
     544            Structure* thisStructure = value[i].get();
     545            if (!thisStructure->isValidOffset(offset))
    521546                return false;
     547            if (inferredType.kind() != InferredType::Top) {
     548                InferredType::Descriptor thisInferredType =
     549                    graph.inferredTypeForProperty(thisStructure, uid);
     550                if (!inferredType.subsumes(thisInferredType))
     551                    return false;
     552            }
    522553        }
    523554        return true;
Note: See TracChangeset for help on using the changeset viewer.