diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp | 149 |
1 files changed, 140 insertions, 9 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp index 251c9a7c0..941f8040c 100644 --- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp +++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013, 2014, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,22 +28,35 @@ #if ENABLE(DFG_JIT) -#include "Operations.h" +#include "CCallHelpers.h" +#include "DFGGraph.h" +#include "JSCInlines.h" +#include "LinkBuffer.h" namespace JSC { namespace DFG { +LazyJSValue LazyJSValue::newString(Graph& graph, const String& string) +{ + LazyJSValue result; + result.m_kind = NewStringImpl; + result.u.stringImpl = graph.m_localStrings.add(string).iterator->impl(); + return result; +} + JSValue LazyJSValue::getValue(VM& vm) const { switch (m_kind) { case KnownValue: - return value(); + return value()->value(); case SingleCharacterString: return jsSingleCharacterString(&vm, u.character); case KnownStringImpl: return jsString(&vm, u.stringImpl); + case NewStringImpl: + return jsString(&vm, AtomicStringImpl::add(u.stringImpl)); } RELEASE_ASSERT_NOT_REACHED(); - return value(); + return JSValue(); } static TriState equalToSingleCharacter(JSValue value, UChar character) @@ -75,17 +88,60 @@ static TriState equalToStringImpl(JSValue value, StringImpl* stringImpl) return triState(WTF::equal(stringImpl, string)); } +const StringImpl* LazyJSValue::tryGetStringImpl(VM& vm) const +{ + switch (m_kind) { + case KnownStringImpl: + case NewStringImpl: + return u.stringImpl; + + case KnownValue: + if (JSString* string = value()->dynamicCast<JSString*>(vm)) + return string->tryGetValueImpl(); + return nullptr; + + default: + return nullptr; + } +} + +String LazyJSValue::tryGetString(Graph& graph) const +{ + switch (m_kind) { + case NewStringImpl: + return u.stringImpl; + + case SingleCharacterString: + return String(&u.character, 1); + + default: + if (const StringImpl* string = tryGetStringImpl(graph.m_vm)) { + unsigned ginormousStringLength = 10000; + if (string->length() > ginormousStringLength) + return String(); + + auto result = graph.m_copiedStrings.add(string, String()); + if (result.isNewEntry) + result.iterator->value = string->isolatedCopy(); + return result.iterator->value; + } + + return String(); + } +} + TriState LazyJSValue::strictEqual(const LazyJSValue& other) const { switch (m_kind) { case KnownValue: switch (other.m_kind) { case KnownValue: - return JSValue::pureStrictEqual(value(), other.value()); + return JSValue::pureStrictEqual(value()->value(), other.value()->value()); case SingleCharacterString: - return equalToSingleCharacter(value(), other.character()); + return equalToSingleCharacter(value()->value(), other.character()); case KnownStringImpl: - return equalToStringImpl(value(), other.stringImpl()); + case NewStringImpl: + return equalToStringImpl(value()->value(), other.stringImpl()); } break; case SingleCharacterString: @@ -93,6 +149,7 @@ TriState LazyJSValue::strictEqual(const LazyJSValue& other) const case SingleCharacterString: return triState(character() == other.character()); case KnownStringImpl: + case NewStringImpl: if (other.stringImpl()->length() != 1) return FalseTriState; return triState(other.stringImpl()->at(0) == character()); @@ -101,8 +158,10 @@ TriState LazyJSValue::strictEqual(const LazyJSValue& other) const } break; case KnownStringImpl: + case NewStringImpl: switch (other.m_kind) { case KnownStringImpl: + case NewStringImpl: return triState(WTF::equal(stringImpl(), other.stringImpl())); default: return other.strictEqual(*this); @@ -113,11 +172,80 @@ TriState LazyJSValue::strictEqual(const LazyJSValue& other) const return FalseTriState; } +uintptr_t LazyJSValue::switchLookupValue(SwitchKind kind) const +{ + // NB. Not every kind of JSValue will be able to give you a switch lookup + // value, and this method will assert, or do bad things, if you use it + // for a kind of value that can't. + switch (m_kind) { + case KnownValue: + switch (kind) { + case SwitchImm: + return value()->value().asInt32(); + case SwitchCell: + return bitwise_cast<uintptr_t>(value()->value().asCell()); + default: + RELEASE_ASSERT_NOT_REACHED(); + return 0; + } + case SingleCharacterString: + switch (kind) { + case SwitchChar: + return character(); + default: + RELEASE_ASSERT_NOT_REACHED(); + return 0; + } + default: + RELEASE_ASSERT_NOT_REACHED(); + return 0; + } +} + +void LazyJSValue::emit(CCallHelpers& jit, JSValueRegs result) const +{ + if (m_kind == KnownValue) { + jit.moveValue(value()->value(), result); + return; + } + + // It must be some kind of cell. +#if USE(JSVALUE32_64) + jit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), result.tagGPR()); +#endif + CCallHelpers::DataLabelPtr label = jit.moveWithPatch( + CCallHelpers::TrustedImmPtr(static_cast<size_t>(0xd1e7beeflu)), + result.payloadGPR()); + + LazyJSValue thisValue = *this; + + // Once we do this, we're committed. Otherwise we leak memory. Note that we call ref/deref + // manually to ensure that there is no concurrency shadiness. We are doing something here + // that might be rather brutal: transfering ownership of this string. + if (m_kind == NewStringImpl) + thisValue.u.stringImpl->ref(); + + CodeBlock* codeBlock = jit.codeBlock(); + + jit.addLinkTask( + [codeBlock, label, thisValue] (LinkBuffer& linkBuffer) { + JSValue realValue = thisValue.getValue(linkBuffer.vm()); + RELEASE_ASSERT(realValue.isCell()); + + codeBlock->addConstant(realValue); + + if (thisValue.m_kind == NewStringImpl) + thisValue.u.stringImpl->deref(); + + linkBuffer.patch(label, realValue.asCell()); + }); +} + void LazyJSValue::dumpInContext(PrintStream& out, DumpContext* context) const { switch (m_kind) { case KnownValue: - value().dumpInContext(out, context); + value()->dumpInContext(out, context); return; case SingleCharacterString: out.print("Lazy:SingleCharacterString("); @@ -125,7 +253,10 @@ void LazyJSValue::dumpInContext(PrintStream& out, DumpContext* context) const out.print(" / ", StringImpl::utf8ForCharacters(&u.character, 1), ")"); return; case KnownStringImpl: - out.print("Lazy:String(", stringImpl(), ")"); + out.print("Lazy:KnownString(", stringImpl(), ")"); + return; + case NewStringImpl: + out.print("Lazy:NewString(", stringImpl(), ")"); return; } RELEASE_ASSERT_NOT_REACHED(); |