Ignore:
Timestamp:
Oct 5, 2017, 12:38:00 AM (8 years ago)
Author:
[email protected]
Message:

Make sure all prototypes under poly proto get added into the VM's prototype map
https://bugs.webkit.org/show_bug.cgi?id=177909

Reviewed by Keith Miller.

JSTests:

  • stress/poly-proto-prototype-map-having-a-bad-time.js: Added.

(assert):
(foo.C):
(foo):
(set x):

Source/JavaScriptCore:

This is an invariant of prototypes that I broke when doing poly proto. This patch fixes it.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/BytecodeList.json:
  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGOperations.cpp:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/JSCInlines.h:
  • runtime/PrototypeMap.cpp:

(JSC::PrototypeMap::addPrototype): Deleted.

  • runtime/PrototypeMap.h:
  • runtime/PrototypeMapInlines.h:

(JSC::PrototypeMap::isPrototype const):
(JSC::PrototypeMap::addPrototype):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r222827 r222901  
    3030#include "ArrayConstructor.h"
    3131#include "BuiltinNames.h"
     32#include "BytecodeStructs.h"
    3233#include "CallFrame.h"
    3334#include "ClonedArguments.h"
     
    9495#define OP_C(index) (exec->r(pc[index].u.operand))
    9596
     97#define GET(operand) (exec->uncheckedR(operand))
     98
    9699#define RETURN_TWO(first, second) do {       \
    97100        return encodeResult(first, second);        \
     
    230233{
    231234    BEGIN();
     235    auto& bytecode = *reinterpret_cast<OpCreateThis*>(pc);
    232236    JSObject* result;
    233     JSObject* constructorAsObject = asObject(OP(2).jsValue());
     237    JSObject* constructorAsObject = asObject(GET(bytecode.callee()).jsValue());
    234238    if (constructorAsObject->type() == JSFunctionType) {
    235239        JSFunction* constructor = jsCast<JSFunction*>(constructorAsObject);
    236         auto& cacheWriteBarrier = pc[4].u.jsCell;
    237         if (!cacheWriteBarrier)
    238             cacheWriteBarrier.set(vm, exec->codeBlock(), constructor);
    239         else if (cacheWriteBarrier.unvalidatedGet() != JSCell::seenMultipleCalleeObjects() && cacheWriteBarrier.get() != constructor)
    240             cacheWriteBarrier.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects());
    241 
    242         size_t inlineCapacity = pc[3].u.operand;
     240        WriteBarrier<JSCell>& cachedCallee = bytecode.cachedCallee();
     241        if (!cachedCallee)
     242            cachedCallee.set(vm, exec->codeBlock(), constructor);
     243        else if (cachedCallee.unvalidatedGet() != JSCell::seenMultipleCalleeObjects() && cachedCallee.get() != constructor)
     244            cachedCallee.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects());
     245
     246        size_t inlineCapacity = bytecode.inlineCapacity();
    243247        Structure* structure = constructor->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure();
    244248        result = constructEmptyObject(exec, structure);
    245         if (structure->hasPolyProto())
    246             result->putDirect(vm, structure->polyProtoOffset(), constructor->prototypeForConstruction(vm, exec));
     249        if (structure->hasPolyProto()) {
     250            JSObject* prototype = constructor->prototypeForConstruction(vm, exec);
     251            result->putDirect(vm, structure->polyProtoOffset(), prototype);
     252            vm.prototypeMap.addPrototype(prototype);
     253        }
    247254    } else {
    248255        // http://ecma-international.org/ecma-262/6.0/#sec-ordinarycreatefromconstructor
Note: See TracChangeset for help on using the changeset viewer.