summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp149
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();