[DevTools] Migrate v8_inspector/public from String16 to String{View,Buffer}.

Using StringView for inbound parameters and StringBuffer for outbound helps to avoid copies in important places (mostly when passing large protocol messages around).

This opens possibility to:
- use WTF::String in core/inspector instead of String16;
- make String16 an alias to std::basic_string<uint16_t> to leverage all existing
optimizations.

One possible optimization is to migrate search utility (in V8StringUtil) to
StringView and avoid any copies of content there.

BUG=637032

Review-Url: https://codereview.chromium.org/2260233002
Cr-Original-Commit-Position: refs/heads/master@{#414846}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 101f402f95f5a67df948347edc4dce050ce482c7
diff --git a/InspectedContext.cpp b/InspectedContext.cpp
index 7129103..baa9808 100644
--- a/InspectedContext.cpp
+++ b/InspectedContext.cpp
@@ -35,9 +35,9 @@
     , m_context(info.context->GetIsolate(), info.context)
     , m_contextId(contextId)
     , m_contextGroupId(info.contextGroupId)
-    , m_origin(info.origin)
-    , m_humanReadableName(info.humanReadableName)
-    , m_auxData(info.auxData)
+    , m_origin(toString16(info.origin))
+    , m_humanReadableName(toString16(info.humanReadableName))
+    , m_auxData(toString16(info.auxData))
     , m_reported(false)
 {
     m_context.SetWeak(this, &InspectedContext::weakCallback, v8::WeakCallbackType::kParameter);
diff --git a/String16STL.h b/String16STL.h
index ffde6c7..0d7e06b 100644
--- a/String16STL.h
+++ b/String16STL.h
@@ -42,6 +42,7 @@
     String16 substring(unsigned pos, unsigned len = UINT_MAX) const { return String16(m_impl.substr(pos, len)); }
     size_t find(const String16& str, unsigned start = 0) const { return m_impl.find(str.m_impl, start); }
     size_t reverseFind(const String16& str, unsigned start = UINT_MAX) const { return m_impl.rfind(str.m_impl, start); }
+    void swap(String16& other) { m_impl.swap(other.m_impl); }
 
     // Convenience methods.
     std::string utf8() const;
diff --git a/String16WTF.h b/String16WTF.h
index b65383a..7c405cb 100644
--- a/String16WTF.h
+++ b/String16WTF.h
@@ -11,7 +11,6 @@
 #include "wtf/text/StringConcatenate.h"
 #include "wtf/text/StringHash.h"
 #include "wtf/text/StringToNumber.h"
-#include "wtf/text/StringView.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
@@ -43,6 +42,7 @@
     String16 substring(unsigned pos, unsigned len = UINT_MAX) const { return m_impl.substring(pos, len); }
     size_t find(const String16& str, unsigned start = 0) const { return m_impl.find(str.impl(), start); }
     size_t reverseFind(const String16& str, unsigned start = UINT_MAX) const { return m_impl.reverseFind(str.impl(), start); }
+    void swap(String16& other) { m_impl.swap(other.m_impl); }
 
     // WTF convenience constructors and helper methods.
     String16(const WebString& other) : String16(String(other)) { }
@@ -53,7 +53,6 @@
     String16(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { }
     bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); }
     operator WTF::String() const { return m_impl; }
-    operator WTF::StringView() const { return StringView(m_impl); }
     operator WebString() { return m_impl; }
     const WTF::String& impl() const { return m_impl; }
 
diff --git a/V8Console.cpp b/V8Console.cpp
index fdcd662..fbb77f1 100644
--- a/V8Console.cpp
+++ b/V8Console.cpp
@@ -358,7 +358,7 @@
     if (title.isEmpty()) {
         std::unique_ptr<V8StackTraceImpl> stackTrace = V8StackTraceImpl::capture(nullptr, 0, 1);
         if (stackTrace)
-            identifier = stackTrace->topSourceURL() + ":" + String16::fromInteger(stackTrace->topLineNumber());
+            identifier = toString16(stackTrace->topSourceURL()) + ":" + String16::fromInteger(stackTrace->topLineNumber());
     } else {
         identifier = title + "@";
     }
@@ -415,7 +415,7 @@
         String16 protocolTitle = helper.firstArgToString("default");
         if (timelinePrefix)
             protocolTitle = "Timeline '" + protocolTitle + "'";
-        client->consoleTime(protocolTitle);
+        client->consoleTime(toStringView(protocolTitle));
 
         v8::Local<v8::Map> timeMap;
         if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap))
@@ -431,7 +431,7 @@
         String16 protocolTitle = helper.firstArgToString("default");
         if (timelinePrefix)
             protocolTitle = "Timeline '" + protocolTitle + "'";
-        client->consoleTimeEnd(protocolTitle);
+        client->consoleTimeEnd(toStringView(protocolTitle));
 
         v8::Local<v8::Map> timeMap;
         if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap))
@@ -467,8 +467,10 @@
 void V8Console::timeStampCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
 {
     ConsoleHelper helper(info);
-    if (V8InspectorClient* client = helper.ensureDebuggerClient())
-        client->consoleTimeStamp(helper.firstArgToString(String16()));
+    if (V8InspectorClient* client = helper.ensureDebuggerClient()) {
+        String16 title = helper.firstArgToString(String16());
+        client->consoleTimeStamp(toStringView(title));
+    }
 }
 
 void V8Console::memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
diff --git a/V8ConsoleMessage.cpp b/V8ConsoleMessage.cpp
index 160ec74..ae7967d 100644
--- a/V8ConsoleMessage.cpp
+++ b/V8ConsoleMessage.cpp
@@ -331,7 +331,7 @@
 {
     std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16()));
     if (stackTrace && !stackTrace->isEmpty()) {
-        message->m_url = stackTrace->topSourceURL();
+        message->m_url = toString16(stackTrace->topSourceURL());
         message->m_lineNumber = stackTrace->topLineNumber();
         message->m_columnNumber = stackTrace->topColumnNumber();
     }
@@ -354,7 +354,7 @@
         clientType = V8ConsoleAPIType::kInfo;
     else if (type == ConsoleAPIType::kClear)
         clientType = V8ConsoleAPIType::kClear;
-    context->inspector()->client()->consoleAPIMessage(context->contextGroupId(), clientType, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get());
+    context->inspector()->client()->consoleAPIMessage(context->contextGroupId(), clientType, toStringView(message->m_message), toStringView(message->m_url), message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get());
 
     return message;
 }
diff --git a/V8Debugger.cpp b/V8Debugger.cpp
index 4b932fa..4364e91 100644
--- a/V8Debugger.cpp
+++ b/V8Debugger.cpp
@@ -717,7 +717,7 @@
 {
     DCHECK(info.context->GetIsolate() == m_isolate);
     int contextId = ++m_lastContextId;
-    String16 debugData = String16::fromInteger(info.contextGroupId) + "," + String16::fromInteger(contextId) + "," + info.auxData;
+    String16 debugData = String16::fromInteger(info.contextGroupId) + "," + String16::fromInteger(contextId) + "," + toString16(info.auxData);
     v8::Context::Scope contextScope(info.context);
     info.context->SetEmbedderData(static_cast<int>(v8::Context::kDebugIdIndex), toV8String(m_isolate, debugData));
     return contextId;
@@ -743,6 +743,13 @@
         allAsyncTasksCanceled();
 }
 
+void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, bool recurring)
+{
+    if (!m_maxAsyncCallStackDepth)
+        return;
+    asyncTaskScheduled(toString16(taskName), task, recurring);
+}
+
 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, bool recurring)
 {
     if (!m_maxAsyncCallStackDepth)
diff --git a/V8Debugger.h b/V8Debugger.h
index 02e762e..25dc781 100644
--- a/V8Debugger.h
+++ b/V8Debugger.h
@@ -9,6 +9,7 @@
 #include "platform/v8_inspector/JavaScriptCallFrame.h"
 #include "platform/v8_inspector/V8DebuggerScript.h"
 #include "platform/v8_inspector/protocol/Runtime.h"
+#include "platform/v8_inspector/public/StringView.h"
 #include "platform/v8_inspector/public/V8ContextInfo.h"
 
 #include <v8-debug.h>
@@ -78,6 +79,7 @@
 
     v8::MaybeLocal<v8::Array> internalProperties(v8::Local<v8::Context>, v8::Local<v8::Value>);
 
+    void asyncTaskScheduled(const StringView& taskName, void* task, bool recurring);
     void asyncTaskScheduled(const String16& taskName, void* task, bool recurring);
     void asyncTaskCanceled(void* task);
     void asyncTaskStarted(void* task);
diff --git a/V8HeapProfilerAgentImpl.cpp b/V8HeapProfilerAgentImpl.cpp
index fb2981f..4ba3695 100644
--- a/V8HeapProfilerAgentImpl.cpp
+++ b/V8HeapProfilerAgentImpl.cpp
@@ -289,8 +289,7 @@
     v8::HandleScope handles(m_isolate);
     v8::Local<v8::Value> value;
     v8::Local<v8::Context> context;
-    String16 objectGroup;
-    if (!m_session->unwrapObject(errorString, objectId, &value, &context, &objectGroup) || value->IsUndefined())
+    if (!m_session->unwrapObject(errorString, toStringView(objectId), &value, &context, nullptr) || value->IsUndefined())
         return;
 
     v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value);
diff --git a/V8InjectedScriptHost.cpp b/V8InjectedScriptHost.cpp
index c308575..79c90f0 100644
--- a/V8InjectedScriptHost.cpp
+++ b/V8InjectedScriptHost.cpp
@@ -134,9 +134,9 @@
         info.GetReturnValue().Set(toV8StringInternalized(isolate, "promise"));
         return;
     }
-    String16 subtype = unwrapInspector(info)->client()->valueSubtype(value);
-    if (!subtype.isEmpty()) {
-        info.GetReturnValue().Set(toV8String(isolate, subtype));
+    std::unique_ptr<StringBuffer> subtype = unwrapInspector(info)->client()->valueSubtype(value);
+    if (subtype) {
+        info.GetReturnValue().Set(toV8String(isolate, subtype->string()));
         return;
     }
 }
diff --git a/V8InspectorImpl.cpp b/V8InspectorImpl.cpp
index 1a56906..d5c6712 100644
--- a/V8InspectorImpl.cpp
+++ b/V8InspectorImpl.cpp
@@ -166,7 +166,7 @@
     return m_debugger->createStackTrace(stackTrace);
 }
 
-std::unique_ptr<V8InspectorSession> V8InspectorImpl::connect(int contextGroupId, protocol::FrontendChannel* channel, const String16* state)
+std::unique_ptr<V8InspectorSession> V8InspectorImpl::connect(int contextGroupId, protocol::FrontendChannel* channel, const StringView& state)
 {
     DCHECK(m_sessions.find(contextGroupId) == m_sessions.cend());
     std::unique_ptr<V8InspectorSessionImpl> session = V8InspectorSessionImpl::create(this, contextGroupId, channel, state);
@@ -265,25 +265,25 @@
     m_isolate->GetCpuProfiler()->SetIdle(false);
 }
 
-unsigned V8InspectorImpl::exceptionThrown(v8::Local<v8::Context> context, const String16& message, v8::Local<v8::Value> exception, const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace> stackTrace, int scriptId)
+unsigned V8InspectorImpl::exceptionThrown(v8::Local<v8::Context> context, const StringView& message, v8::Local<v8::Value> exception, const StringView& detailedMessage, const StringView& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace> stackTrace, int scriptId)
 {
     int contextGroupId = V8Debugger::getGroupId(context);
     if (!contextGroupId || m_muteExceptionsMap[contextGroupId])
         return 0;
     std::unique_ptr<V8StackTraceImpl> stackTraceImpl = wrapUnique(static_cast<V8StackTraceImpl*>(stackTrace.release()));
     unsigned exceptionId = nextExceptionId();
-    std::unique_ptr<V8ConsoleMessage> consoleMessage = V8ConsoleMessage::createForException(m_client->currentTimeMS(), detailedMessage, url, lineNumber, columnNumber, std::move(stackTraceImpl), scriptId, m_isolate, message, V8Debugger::contextId(context), exception, exceptionId);
+    std::unique_ptr<V8ConsoleMessage> consoleMessage = V8ConsoleMessage::createForException(m_client->currentTimeMS(), toString16(detailedMessage), toString16(url), lineNumber, columnNumber, std::move(stackTraceImpl), scriptId, m_isolate, toString16(message), V8Debugger::contextId(context), exception, exceptionId);
     ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage));
     return exceptionId;
 }
 
-void V8InspectorImpl::exceptionRevoked(v8::Local<v8::Context> context, unsigned exceptionId, const String16& message)
+void V8InspectorImpl::exceptionRevoked(v8::Local<v8::Context> context, unsigned exceptionId, const StringView& message)
 {
     int contextGroupId = V8Debugger::getGroupId(context);
     if (!contextGroupId)
         return;
 
-    std::unique_ptr<V8ConsoleMessage> consoleMessage = V8ConsoleMessage::createForRevokedException(m_client->currentTimeMS(), message, exceptionId);
+    std::unique_ptr<V8ConsoleMessage> consoleMessage = V8ConsoleMessage::createForRevokedException(m_client->currentTimeMS(), toString16(message), exceptionId);
     ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage));
 }
 
@@ -292,7 +292,7 @@
     return m_debugger->captureStackTrace(fullStack);
 }
 
-void V8InspectorImpl::asyncTaskScheduled(const String16& taskName, void* task, bool recurring)
+void V8InspectorImpl::asyncTaskScheduled(const StringView& taskName, void* task, bool recurring)
 {
     m_debugger->asyncTaskScheduled(taskName, task, recurring);
 }
diff --git a/V8InspectorImpl.h b/V8InspectorImpl.h
index 395c48d..a363bae 100644
--- a/V8InspectorImpl.h
+++ b/V8InspectorImpl.h
@@ -67,7 +67,7 @@
     v8::Local<v8::Context> regexContext();
 
     // V8Inspector implementation.
-    std::unique_ptr<V8InspectorSession> connect(int contextGroupId, protocol::FrontendChannel*, const String16* state) override;
+    std::unique_ptr<V8InspectorSession> connect(int contextGroupId, protocol::FrontendChannel*, const StringView& state) override;
     void contextCreated(const V8ContextInfo&) override;
     void contextDestroyed(v8::Local<v8::Context>) override;
     void resetContextGroup(int contextGroupId) override;
@@ -75,11 +75,11 @@
     void didExecuteScript(v8::Local<v8::Context>) override;
     void idleStarted() override;
     void idleFinished() override;
-    unsigned exceptionThrown(v8::Local<v8::Context>, const String16& message, v8::Local<v8::Value> exception, const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace>, int scriptId) override;
-    void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId, const String16& message) override;
+    unsigned exceptionThrown(v8::Local<v8::Context>, const StringView& message, v8::Local<v8::Value> exception, const StringView& detailedMessage, const StringView& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace>, int scriptId) override;
+    void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId, const StringView& message) override;
     std::unique_ptr<V8StackTrace> createStackTrace(v8::Local<v8::StackTrace>) override;
     std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) override;
-    void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) override;
+    void asyncTaskScheduled(const StringView& taskName, void* task, bool recurring) override;
     void asyncTaskCanceled(void* task) override;
     void asyncTaskStarted(void* task) override;
     void asyncTaskFinished(void* task) override;
diff --git a/V8InspectorSessionImpl.cpp b/V8InspectorSessionImpl.cpp
index 51b288d..3aacf5a 100644
--- a/V8InspectorSessionImpl.cpp
+++ b/V8InspectorSessionImpl.cpp
@@ -22,22 +22,22 @@
 namespace v8_inspector {
 
 // static
-bool V8InspectorSession::canDispatchMethod(const String16& method)
+bool V8InspectorSession::canDispatchMethod(const StringView& method)
 {
-    return method.startsWith(protocol::Runtime::Metainfo::commandPrefix)
-        || method.startsWith(protocol::Debugger::Metainfo::commandPrefix)
-        || method.startsWith(protocol::Profiler::Metainfo::commandPrefix)
-        || method.startsWith(protocol::HeapProfiler::Metainfo::commandPrefix)
-        || method.startsWith(protocol::Console::Metainfo::commandPrefix)
-        || method.startsWith(protocol::Schema::Metainfo::commandPrefix);
+    return stringViewStartsWith(method, protocol::Runtime::Metainfo::commandPrefix)
+        || stringViewStartsWith(method, protocol::Debugger::Metainfo::commandPrefix)
+        || stringViewStartsWith(method, protocol::Profiler::Metainfo::commandPrefix)
+        || stringViewStartsWith(method, protocol::HeapProfiler::Metainfo::commandPrefix)
+        || stringViewStartsWith(method, protocol::Console::Metainfo::commandPrefix)
+        || stringViewStartsWith(method, protocol::Schema::Metainfo::commandPrefix);
 }
 
-std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(V8InspectorImpl* inspector, int contextGroupId, protocol::FrontendChannel* channel, const String16* state)
+std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(V8InspectorImpl* inspector, int contextGroupId, protocol::FrontendChannel* channel, const StringView& state)
 {
     return wrapUnique(new V8InspectorSessionImpl(inspector, contextGroupId, channel, state));
 }
 
-V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector, int contextGroupId, protocol::FrontendChannel* channel, const String16* savedState)
+V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector, int contextGroupId, protocol::FrontendChannel* channel, const StringView& savedState)
     : m_contextGroupId(contextGroupId)
     , m_inspector(inspector)
     , m_customObjectFormatterEnabled(false)
@@ -50,8 +50,8 @@
     , m_consoleAgent(nullptr)
     , m_schemaAgent(nullptr)
 {
-    if (savedState) {
-        std::unique_ptr<protocol::Value> state = protocol::parseJSON(*savedState);
+    if (savedState.length()) {
+        std::unique_ptr<protocol::Value> state = protocol::parseJSON(toString16(savedState));
         if (state)
             m_state = protocol::DictionaryValue::cast(std::move(state));
         if (!m_state)
@@ -78,7 +78,7 @@
     m_schemaAgent = wrapUnique(new V8SchemaAgentImpl(this, channel, agentState(protocol::Schema::Metainfo::domainName)));
     protocol::Schema::Dispatcher::wire(&m_dispatcher, m_schemaAgent.get());
 
-    if (savedState) {
+    if (savedState.length()) {
         m_runtimeAgent->restore();
         m_debuggerAgent->restore();
         m_heapProfilerAgent->restore();
@@ -176,6 +176,11 @@
     return objectId ? findInjectedScript(errorString, objectId->contextId()) : nullptr;
 }
 
+void V8InspectorSessionImpl::releaseObjectGroup(const StringView& objectGroup)
+{
+    releaseObjectGroup(toString16(objectGroup));
+}
+
 void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup)
 {
     const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->contextGroup(m_contextGroupId);
@@ -198,9 +203,9 @@
     }
 }
 
-bool V8InspectorSessionImpl::unwrapObject(ErrorString* errorString, const String16& objectId, v8::Local<v8::Value>* object, v8::Local<v8::Context>* context, String16* objectGroup)
+bool V8InspectorSessionImpl::unwrapObject(ErrorString* errorString, const StringView& objectId, v8::Local<v8::Value>* object, v8::Local<v8::Context>* context, std::unique_ptr<StringBuffer>* objectGroup)
 {
-    std::unique_ptr<RemoteObjectId> remoteId = RemoteObjectId::parse(errorString, objectId);
+    std::unique_ptr<RemoteObjectId> remoteId = RemoteObjectId::parse(errorString, toString16(objectId));
     if (!remoteId)
         return false;
     InjectedScript* injectedScript = findInjectedScript(errorString, remoteId.get());
@@ -209,13 +214,16 @@
     if (!injectedScript->findObject(errorString, *remoteId, object))
         return false;
     *context = injectedScript->context()->context();
-    *objectGroup = injectedScript->objectGroupName(*remoteId);
+    if (objectGroup) {
+        String16 group = injectedScript->objectGroupName(*remoteId);
+        *objectGroup = StringBufferImpl::adopt(group);
+    }
     return true;
 }
 
-std::unique_ptr<protocol::Runtime::API::RemoteObject> V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context, v8::Local<v8::Value> value, const String16& groupName)
+std::unique_ptr<protocol::Runtime::API::RemoteObject> V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context, v8::Local<v8::Value> value, const StringView& groupName)
 {
-    return wrapObject(context, value, groupName, false);
+    return wrapObject(context, value, toString16(groupName), false);
 }
 
 std::unique_ptr<protocol::Runtime::RemoteObject> V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context, v8::Local<v8::Value> value, const String16& groupName, bool generatePreview)
@@ -258,14 +266,15 @@
         agent->reportExecutionContextCreated(idContext.second.get());
 }
 
-void V8InspectorSessionImpl::dispatchProtocolMessage(const String16& message)
+void V8InspectorSessionImpl::dispatchProtocolMessage(const StringView& message)
 {
-    m_dispatcher.dispatch(message);
+    m_dispatcher.dispatch(parseJSON(message));
 }
 
-String16 V8InspectorSessionImpl::stateJSON()
+std::unique_ptr<StringBuffer> V8InspectorSessionImpl::stateJSON()
 {
-    return m_state->toJSONString();
+    String16 json = m_state->toJSONString();
+    return StringBufferImpl::adopt(json);
 }
 
 std::unique_ptr<protocol::Array<protocol::Schema::API::Domain>> V8InspectorSessionImpl::supportedDomains()
@@ -302,9 +311,9 @@
     return m_inspectedObjects[num].get();
 }
 
-void V8InspectorSessionImpl::schedulePauseOnNextStatement(const String16& breakReason, const String16& breakDetails)
+void V8InspectorSessionImpl::schedulePauseOnNextStatement(const StringView& breakReason, const StringView& breakDetails)
 {
-    m_debuggerAgent->schedulePauseOnNextStatement(breakReason, protocol::DictionaryValue::cast(parseJSON(breakDetails)));
+    m_debuggerAgent->schedulePauseOnNextStatement(toString16(breakReason), protocol::DictionaryValue::cast(parseJSON(breakDetails)));
 }
 
 void V8InspectorSessionImpl::cancelPauseOnNextStatement()
@@ -312,9 +321,9 @@
     m_debuggerAgent->cancelPauseOnNextStatement();
 }
 
-void V8InspectorSessionImpl::breakProgram(const String16& breakReason, const String16& breakDetails)
+void V8InspectorSessionImpl::breakProgram(const StringView& breakReason, const StringView& breakDetails)
 {
-    m_debuggerAgent->breakProgram(breakReason, protocol::DictionaryValue::cast(parseJSON(breakDetails)));
+    m_debuggerAgent->breakProgram(toString16(breakReason), protocol::DictionaryValue::cast(parseJSON(breakDetails)));
 }
 
 void V8InspectorSessionImpl::setSkipAllPauses(bool skip)
@@ -335,9 +344,10 @@
     m_debuggerAgent->stepOver(&errorString);
 }
 
-std::unique_ptr<protocol::Array<protocol::Debugger::API::SearchMatch>> V8InspectorSessionImpl::searchInTextByLines(const String16& text, const String16& query, bool caseSensitive, bool isRegex)
+std::unique_ptr<protocol::Array<protocol::Debugger::API::SearchMatch>> V8InspectorSessionImpl::searchInTextByLines(const StringView& text, const StringView& query, bool caseSensitive, bool isRegex)
 {
-    std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches = searchInTextByLinesImpl(this, text, query, caseSensitive, isRegex);
+    // TODO(dgozman): search may operate on StringView and avoid copying |text|.
+    std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches = searchInTextByLinesImpl(this, toString16(text), toString16(query), caseSensitive, isRegex);
     std::unique_ptr<protocol::Array<protocol::Debugger::API::SearchMatch>> result = protocol::Array<protocol::Debugger::API::SearchMatch>::create();
     for (size_t i = 0; i < matches.size(); ++i)
         result->addItem(std::move(matches[i]));
diff --git a/V8InspectorSessionImpl.h b/V8InspectorSessionImpl.h
index 18164b7..118d590 100644
--- a/V8InspectorSessionImpl.h
+++ b/V8InspectorSessionImpl.h
@@ -31,7 +31,7 @@
 class V8InspectorSessionImpl : public V8InspectorSession {
     PROTOCOL_DISALLOW_COPY(V8InspectorSessionImpl);
 public:
-    static std::unique_ptr<V8InspectorSessionImpl> create(V8InspectorImpl*, int contextGroupId, protocol::FrontendChannel*, const String16* state);
+    static std::unique_ptr<V8InspectorSessionImpl> create(V8InspectorImpl*, int contextGroupId, protocol::FrontendChannel*, const StringView& state);
     ~V8InspectorSessionImpl();
 
     V8InspectorImpl* inspector() const { return m_inspector; }
@@ -51,28 +51,29 @@
     std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName, bool generatePreview);
     std::unique_ptr<protocol::Runtime::RemoteObject> wrapTable(v8::Local<v8::Context>, v8::Local<v8::Value> table, v8::Local<v8::Value> columns);
     std::vector<std::unique_ptr<protocol::Schema::Domain>> supportedDomainsImpl();
+    void releaseObjectGroup(const String16& objectGroup);
 
     // V8InspectorSession implementation.
-    void dispatchProtocolMessage(const String16& message) override;
-    String16 stateJSON() override;
-    std::unique_ptr<protocol::Array<protocol::Schema::API::Domain>> supportedDomains() override;
+    void dispatchProtocolMessage(const StringView& message) override;
+    std::unique_ptr<StringBuffer> stateJSON() override;
+    std::unique_ptr<blink::protocol::Array<blink::protocol::Schema::API::Domain>> supportedDomains() override;
     void addInspectedObject(std::unique_ptr<V8InspectorSession::Inspectable>) override;
-    void schedulePauseOnNextStatement(const String16& breakReason, const String16& breakDetails) override;
+    void schedulePauseOnNextStatement(const StringView& breakReason, const StringView& breakDetails) override;
     void cancelPauseOnNextStatement() override;
-    void breakProgram(const String16& breakReason, const String16& breakDetails) override;
+    void breakProgram(const StringView& breakReason, const StringView& breakDetails) override;
     void setSkipAllPauses(bool) override;
     void resume() override;
     void stepOver() override;
-    std::unique_ptr<protocol::Array<protocol::Debugger::API::SearchMatch>> searchInTextByLines(const String16& text, const String16& query, bool caseSensitive, bool isRegex) override;
-    void releaseObjectGroup(const String16& objectGroup) override;
-    bool unwrapObject(ErrorString*, const String16& objectId, v8::Local<v8::Value>*, v8::Local<v8::Context>*, String16* objectGroup) override;
-    std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName) override;
+    std::unique_ptr<protocol::Array<protocol::Debugger::API::SearchMatch>> searchInTextByLines(const StringView& text, const StringView& query, bool caseSensitive, bool isRegex) override;
+    void releaseObjectGroup(const StringView& objectGroup) override;
+    bool unwrapObject(ErrorString*, const StringView& objectId, v8::Local<v8::Value>*, v8::Local<v8::Context>*, std::unique_ptr<StringBuffer>* objectGroup) override;
+    std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const StringView& groupName) override;
 
     V8InspectorSession::Inspectable* inspectedObject(unsigned num);
     static const unsigned kInspectedObjectBufferSize = 5;
 
 private:
-    V8InspectorSessionImpl(V8InspectorImpl*, int contextGroupId, protocol::FrontendChannel*, const String16* state);
+    V8InspectorSessionImpl(V8InspectorImpl*, int contextGroupId, protocol::FrontendChannel*, const StringView& state);
     protocol::DictionaryValue* agentState(const String16& name);
 
     int m_contextGroupId;
diff --git a/V8ProfilerAgentImpl.cpp b/V8ProfilerAgentImpl.cpp
index f214d4f..b966763 100644
--- a/V8ProfilerAgentImpl.cpp
+++ b/V8ProfilerAgentImpl.cpp
@@ -5,6 +5,7 @@
 #include "platform/v8_inspector/V8ProfilerAgentImpl.h"
 
 #include "platform/v8_inspector/Atomics.h"
+#include "platform/v8_inspector/V8Debugger.h"
 #include "platform/v8_inspector/V8InspectorImpl.h"
 #include "platform/v8_inspector/V8InspectorSessionImpl.h"
 #include "platform/v8_inspector/V8StackTraceImpl.h"
@@ -122,9 +123,9 @@
 
 std::unique_ptr<protocol::Debugger::Location> currentDebugLocation(V8InspectorImpl* inspector)
 {
-    std::unique_ptr<V8StackTrace> callStack = inspector->captureStackTrace(1);
+    std::unique_ptr<V8StackTraceImpl> callStack = inspector->debugger()->captureStackTrace(false /* fullStack */);
     auto location = protocol::Debugger::Location::create()
-        .setScriptId(callStack->topScriptId())
+        .setScriptId(toString16(callStack->topScriptId()))
         .setLineNumber(callStack->topLineNumber()).build();
     location->setColumnNumber(callStack->topColumnNumber());
     return location;
diff --git a/V8RuntimeAgentImpl.cpp b/V8RuntimeAgentImpl.cpp
index c5a0449..3af7617 100644
--- a/V8RuntimeAgentImpl.cpp
+++ b/V8RuntimeAgentImpl.cpp
@@ -116,7 +116,7 @@
         if (stack)
             exceptionDetails->setStackTrace(stack->buildInspectorObjectImpl());
         if (stack && !stack->isEmpty())
-            exceptionDetails->setScriptId(stack->topScriptId());
+            exceptionDetails->setScriptId(toString16(stack->topScriptId()));
         handler->m_callback->sendSuccess(handler->wrapObject(value), std::move(exceptionDetails));
     }
 
diff --git a/V8StackTraceImpl.cpp b/V8StackTraceImpl.cpp
index e0bab17..8f7c5a6 100644
--- a/V8StackTraceImpl.cpp
+++ b/V8StackTraceImpl.cpp
@@ -185,10 +185,10 @@
 {
 }
 
-String16 V8StackTraceImpl::topSourceURL() const
+StringView V8StackTraceImpl::topSourceURL() const
 {
     DCHECK(m_frames.size());
-    return m_frames[0].m_scriptName;
+    return toStringView(m_frames[0].m_scriptName);
 }
 
 int V8StackTraceImpl::topLineNumber() const
@@ -203,16 +203,16 @@
     return m_frames[0].m_columnNumber;
 }
 
-String16 V8StackTraceImpl::topFunctionName() const
+StringView V8StackTraceImpl::topFunctionName() const
 {
     DCHECK(m_frames.size());
-    return m_frames[0].m_functionName;
+    return toStringView(m_frames[0].m_functionName);
 }
 
-String16 V8StackTraceImpl::topScriptId() const
+StringView V8StackTraceImpl::topScriptId() const
 {
     DCHECK(m_frames.size());
-    return m_frames[0].m_scriptId;
+    return toStringView(m_frames[0].m_scriptId);
 }
 
 std::unique_ptr<protocol::Runtime::StackTrace> V8StackTraceImpl::buildInspectorObjectImpl() const
@@ -245,7 +245,7 @@
     return buildInspectorObjectImpl();
 }
 
-String16 V8StackTraceImpl::toString() const
+std::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const
 {
     String16Builder stackTrace;
     for (size_t i = 0; i < m_frames.size(); ++i) {
@@ -259,7 +259,8 @@
         stackTrace.append(String16::fromInteger(frame.columnNumber()));
         stackTrace.append(')');
     }
-    return stackTrace.toString();
+    String16 string = stackTrace.toString();
+    return StringBufferImpl::adopt(string);
 }
 
 } // namespace v8_inspector
diff --git a/V8StackTraceImpl.h b/V8StackTraceImpl.h
index 25ad3ab..2795cb4 100644
--- a/V8StackTraceImpl.h
+++ b/V8StackTraceImpl.h
@@ -64,13 +64,13 @@
 
     // V8StackTrace implementation.
     bool isEmpty() const override { return !m_frames.size(); };
-    String16 topSourceURL() const override;
+    StringView topSourceURL() const override;
     int topLineNumber() const override;
     int topColumnNumber() const override;
-    String16 topScriptId() const override;
-    String16 topFunctionName() const override;
+    StringView topScriptId() const override;
+    StringView topFunctionName() const override;
     std::unique_ptr<protocol::Runtime::API::StackTrace> buildInspectorObject() const override;
-    String16 toString() const override;
+    std::unique_ptr<StringBuffer> toString() const override;
 
 private:
     V8StackTraceImpl(int contextGroupId, const String16& description, std::vector<Frame>& frames, std::unique_ptr<V8StackTraceImpl> parent);
diff --git a/V8StringUtil.cpp b/V8StringUtil.cpp
index d078da6..2750f03 100644
--- a/V8StringUtil.cpp
+++ b/V8StringUtil.cpp
@@ -4,6 +4,7 @@
 
 #include "platform/v8_inspector/V8StringUtil.h"
 
+#include "platform/inspector_protocol/InspectorProtocol.h"
 #include "platform/v8_inspector/V8InspectorImpl.h"
 #include "platform/v8_inspector/V8InspectorSessionImpl.h"
 #include "platform/v8_inspector/V8Regex.h"
@@ -167,6 +168,15 @@
     return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kInternalized).ToLocalChecked();
 }
 
+v8::Local<v8::String> toV8String(v8::Isolate* isolate, const StringView& string)
+{
+    if (!string.length())
+        return v8::String::Empty(isolate);
+    if (string.is8Bit())
+        return v8::String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(string.characters8()), v8::NewStringType::kNormal, string.length()).ToLocalChecked();
+    return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*>(string.characters16()), v8::NewStringType::kNormal, string.length()).ToLocalChecked();
+}
+
 String16 toProtocolString(v8::Local<v8::String> value)
 {
     if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
@@ -183,6 +193,49 @@
     return toProtocolString(value.As<v8::String>());
 }
 
+String16 toString16(const StringView& string)
+{
+    if (!string.length())
+        return String16();
+    if (string.is8Bit())
+        return String16(reinterpret_cast<const char*>(string.characters8()), string.length());
+    return String16(reinterpret_cast<const UChar*>(string.characters16()), string.length());
+}
+
+StringView toStringView(const String16& string)
+{
+    if (string.isEmpty())
+        return StringView();
+    return StringView(reinterpret_cast<const uint16_t*>(string.characters16()), string.length());
+}
+
+bool stringViewStartsWith(const StringView& string, const char* prefix)
+{
+    if (!string.length())
+        return !(*prefix);
+    if (string.is8Bit()) {
+        for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
+            if (string.characters8()[i] != prefix[j])
+                return false;
+        }
+    } else {
+        for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
+            if (string.characters16()[i] != prefix[j])
+                return false;
+        }
+    }
+    return true;
+}
+
+std::unique_ptr<protocol::Value> parseJSON(const StringView& string)
+{
+    if (!string.length())
+        return nullptr;
+    if (string.is8Bit())
+        return blink::protocol::parseJSON(string.characters8(), string.length());
+    return blink::protocol::parseJSON(string.characters16(), string.length());
+}
+
 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> searchInTextByLinesImpl(V8InspectorSession* session, const String16& text, const String16& query, const bool caseSensitive, const bool isRegex)
 {
     std::unique_ptr<V8Regex> regex = createSearchRegex(static_cast<V8InspectorSessionImpl*>(session)->inspector(), query, caseSensitive, isRegex);
@@ -277,4 +330,23 @@
     return nullptr;
 }
 
+// static
+std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string)
+{
+    String16 owner = toString16(string);
+    return StringBufferImpl::adopt(owner);
+}
+
+// static
+std::unique_ptr<StringBufferImpl> StringBufferImpl::adopt(String16& string)
+{
+    return wrapUnique(new StringBufferImpl(string));
+}
+
+StringBufferImpl::StringBufferImpl(String16& string)
+{
+    m_owner.swap(string);
+    m_string = toStringView(m_owner);
+}
+
 } // namespace v8_inspector
diff --git a/V8StringUtil.h b/V8StringUtil.h
index 2245c8f..db1e4d0 100644
--- a/V8StringUtil.h
+++ b/V8StringUtil.h
@@ -7,6 +7,8 @@
 
 #include "platform/inspector_protocol/InspectorProtocol.h"
 #include "platform/v8_inspector/protocol/Debugger.h"
+#include "platform/v8_inspector/public/StringBuffer.h"
+#include "platform/v8_inspector/public/StringView.h"
 #include <v8.h>
 
 namespace v8_inspector {
@@ -20,14 +22,33 @@
 v8::Local<v8::String> toV8String(v8::Isolate*, const String16&);
 v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const String16&);
 v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const char*);
+v8::Local<v8::String> toV8String(v8::Isolate*, const StringView&);
 
 String16 toProtocolString(v8::Local<v8::String>);
 String16 toProtocolStringWithTypeCheck(v8::Local<v8::Value>);
+String16 toString16(const StringView&);
+StringView toStringView(const String16&);
+
+bool stringViewStartsWith(const StringView&, const char*);
+std::unique_ptr<protocol::Value> parseJSON(const StringView& json);
 
 String16 findSourceURL(const String16& content, bool multiline);
 String16 findSourceMapURL(const String16& content, bool multiline);
 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> searchInTextByLinesImpl(V8InspectorSession*, const String16& text, const String16& query, bool caseSensitive, bool isRegex);
 
+class StringBufferImpl : public StringBuffer {
+    PROTOCOL_DISALLOW_COPY(StringBufferImpl);
+public:
+    // Destroys string's content.
+    static std::unique_ptr<StringBufferImpl> adopt(String16&);
+    const StringView& string() override { return m_string; }
+
+private:
+    explicit StringBufferImpl(String16&);
+    String16 m_owner;
+    StringView m_string;
+};
+
 } //  namespace v8_inspector
 
 
diff --git a/public/StringBuffer.h b/public/StringBuffer.h
new file mode 100644
index 0000000..862db06
--- /dev/null
+++ b/public/StringBuffer.h
@@ -0,0 +1,26 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Note: this include guard is very specific to not clash with wtf. Will be changed after moving out of blink.
+#ifndef v8_inspector_public_StringBuffer_h
+#define v8_inspector_public_StringBuffer_h
+
+#include "platform/PlatformExport.h"
+#include "platform/v8_inspector/public/StringView.h"
+
+#include <memory>
+
+namespace v8_inspector {
+
+class PLATFORM_EXPORT StringBuffer {
+public:
+    virtual ~StringBuffer() { }
+    virtual const StringView& string() = 0;
+    // This method copies contents.
+    static std::unique_ptr<StringBuffer> create(const StringView&);
+};
+
+} // namespace v8_inspector
+
+#endif // v8_inspector_public_StringBuffer_h
diff --git a/public/StringView.h b/public/StringView.h
new file mode 100644
index 0000000..333cebf
--- /dev/null
+++ b/public/StringView.h
@@ -0,0 +1,51 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Note: this include guard is very specific to not clash with wtf. Will be changed after moving out of blink.
+#ifndef v8_inspector_public_StringView_h
+#define v8_inspector_public_StringView_h
+
+#include "platform/PlatformExport.h"
+
+#include <cctype>
+#include <stdint.h>
+
+namespace v8_inspector {
+
+class PLATFORM_EXPORT StringView {
+public:
+    StringView()
+        : m_is8Bit(true)
+        , m_length(0)
+        , m_characters8(nullptr) {}
+
+    StringView(const uint8_t* characters, unsigned length)
+        : m_is8Bit(true)
+        , m_length(length)
+        , m_characters8(characters) {}
+
+    StringView(const uint16_t* characters, unsigned length)
+        : m_is8Bit(false)
+        , m_length(length)
+        , m_characters16(characters) {}
+
+    bool is8Bit() const { return m_is8Bit; }
+    unsigned length() const { return m_length; }
+
+    // TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used here.
+    const uint8_t* characters8() const { return m_characters8; }
+    const uint16_t* characters16() const { return m_characters16; }
+
+private:
+    bool m_is8Bit;
+    unsigned m_length;
+    union {
+        const uint8_t* m_characters8;
+        const uint16_t* m_characters16;
+    };
+};
+
+} // namespace v8_inspector
+
+#endif // v8_inspector_public_StringView_h
diff --git a/public/V8ContextInfo.h b/public/V8ContextInfo.h
index 24570a4..abb33b2 100644
--- a/public/V8ContextInfo.h
+++ b/public/V8ContextInfo.h
@@ -5,7 +5,7 @@
 #ifndef V8ContextInfo_h
 #define V8ContextInfo_h
 
-#include "platform/inspector_protocol/InspectorProtocol.h"
+#include "platform/v8_inspector/public/StringView.h"
 
 #include <v8.h>
 
@@ -13,7 +13,7 @@
 
 class V8ContextInfo {
 public:
-    V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId, const String16& humanReadableName)
+    V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId, const StringView& humanReadableName)
         : context(context)
         , contextGroupId(contextGroupId)
         , humanReadableName(humanReadableName)
@@ -26,10 +26,19 @@
     // V8DebuggerAgent to notify about events in the context.
     // |contextGroupId| must be non-0.
     int contextGroupId;
-    String16 humanReadableName;
-    String16 origin;
-    String16 auxData;
+    StringView humanReadableName;
+    StringView origin;
+    StringView auxData;
     bool hasMemoryOnConsole;
+
+private:
+    // Disallow copying and allocating this one.
+    enum NotNullTagEnum { NotNullLiteral };
+    void* operator new(size_t) = delete;
+    void* operator new(size_t, NotNullTagEnum, void*) = delete;
+    void* operator new(size_t, void*) = delete;
+    V8ContextInfo(const V8ContextInfo&) = delete;
+    V8ContextInfo& operator=(const V8ContextInfo&) = delete;
 };
 
 } // namespace v8_inspector
diff --git a/public/V8Inspector.h b/public/V8Inspector.h
index bb07847..646c024 100644
--- a/public/V8Inspector.h
+++ b/public/V8Inspector.h
@@ -5,11 +5,13 @@
 #ifndef V8Inspector_h
 #define V8Inspector_h
 
-#include "platform/inspector_protocol/InspectorProtocol.h"
+#include "platform/v8_inspector/public/StringView.h"
 #include "platform/v8_inspector/public/V8ContextInfo.h"
 
 #include <v8.h>
 
+namespace blink { namespace protocol { class FrontendChannel; }}
+
 namespace v8_inspector {
 
 class V8InspectorClient;
@@ -33,18 +35,18 @@
     virtual void idleFinished() = 0;
 
     // Async stack traces instrumentation.
-    virtual void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) = 0;
+    virtual void asyncTaskScheduled(const StringView& taskName, void* task, bool recurring) = 0;
     virtual void asyncTaskCanceled(void* task) = 0;
     virtual void asyncTaskStarted(void* task) = 0;
     virtual void asyncTaskFinished(void* task) = 0;
     virtual void allAsyncTasksCanceled() = 0;
 
     // Exceptions instrumentation.
-    virtual unsigned exceptionThrown(v8::Local<v8::Context>, const String16& message, v8::Local<v8::Value> exception, const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace>, int scriptId) = 0;
-    virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId, const String16& message) = 0;
+    virtual unsigned exceptionThrown(v8::Local<v8::Context>, const StringView& message, v8::Local<v8::Value> exception, const StringView& detailedMessage, const StringView& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace>, int scriptId) = 0;
+    virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId, const StringView& message) = 0;
 
     // API methods.
-    virtual std::unique_ptr<V8InspectorSession> connect(int contextGroupId, blink::protocol::FrontendChannel*, const String16* state) = 0;
+    virtual std::unique_ptr<V8InspectorSession> connect(int contextGroupId, blink::protocol::FrontendChannel*, const StringView& state) = 0;
     virtual std::unique_ptr<V8StackTrace> createStackTrace(v8::Local<v8::StackTrace>) = 0;
     virtual std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) = 0;
 };
diff --git a/public/V8InspectorClient.h b/public/V8InspectorClient.h
index eb3e2ae..aa30bf4 100644
--- a/public/V8InspectorClient.h
+++ b/public/V8InspectorClient.h
@@ -5,7 +5,8 @@
 #ifndef V8InspectorClient_h
 #define V8InspectorClient_h
 
-#include "platform/inspector_protocol/InspectorProtocol.h"
+#include "platform/v8_inspector/public/StringBuffer.h"
+#include "platform/v8_inspector/public/StringView.h"
 
 #include <v8.h>
 
@@ -29,7 +30,7 @@
     virtual void beginUserGesture() { }
     virtual void endUserGesture() { }
 
-    virtual String16 valueSubtype(v8::Local<v8::Value>) { return String16(); }
+    virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) { return nullptr; }
     virtual bool formatAccessorsAsProperties(v8::Local<v8::Value>) { return false; }
     virtual bool isInspectableHeapObject(v8::Local<v8::Object>) { return true; }
 
@@ -38,12 +39,12 @@
     virtual void endEnsureAllContextsInGroup(int contextGroupId) { }
 
     virtual void installAdditionalCommandLineAPI(v8::Local<v8::Context>, v8::Local<v8::Object>) { }
-    virtual void consoleAPIMessage(int contextGroupId, V8ConsoleAPIType, const String16& message, const String16& url, unsigned lineNumber, unsigned columnNumber, V8StackTrace*) { }
+    virtual void consoleAPIMessage(int contextGroupId, V8ConsoleAPIType, const StringView& message, const StringView& url, unsigned lineNumber, unsigned columnNumber, V8StackTrace*) { }
     virtual v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*, v8::Local<v8::Context>) { return v8::MaybeLocal<v8::Value>(); }
 
-    virtual void consoleTime(const String16& title) { }
-    virtual void consoleTimeEnd(const String16& title) { }
-    virtual void consoleTimeStamp(const String16& title) { }
+    virtual void consoleTime(const StringView& title) { }
+    virtual void consoleTimeEnd(const StringView& title) { }
+    virtual void consoleTimeStamp(const StringView& title) { }
     virtual double currentTimeMS() { return 0; }
     typedef void (*TimerCallback)(void*);
     virtual void startRepeatingTimer(double, TimerCallback, void* data) { }
diff --git a/public/V8InspectorSession.h b/public/V8InspectorSession.h
index 2954ae3..e45d81a 100644
--- a/public/V8InspectorSession.h
+++ b/public/V8InspectorSession.h
@@ -5,7 +5,8 @@
 #ifndef V8InspectorSession_h
 #define V8InspectorSession_h
 
-#include "platform/inspector_protocol/InspectorProtocol.h"
+#include "platform/v8_inspector/public/StringBuffer.h"
+#include "platform/v8_inspector/public/StringView.h"
 #include "platform/v8_inspector/public/protocol/Debugger.h"
 #include "platform/v8_inspector/public/protocol/Runtime.h"
 #include "platform/v8_inspector/public/protocol/Schema.h"
@@ -27,24 +28,24 @@
     virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0;
 
     // Dispatching protocol messages.
-    static bool canDispatchMethod(const String16& method);
-    virtual void dispatchProtocolMessage(const String16& message) = 0;
-    virtual String16 stateJSON() = 0;
+    static bool canDispatchMethod(const StringView& method);
+    virtual void dispatchProtocolMessage(const StringView& message) = 0;
+    virtual std::unique_ptr<StringBuffer> stateJSON() = 0;
     virtual std::unique_ptr<blink::protocol::Array<blink::protocol::Schema::API::Domain>> supportedDomains() = 0;
 
     // Debugger actions.
-    virtual void schedulePauseOnNextStatement(const String16& breakReason, const String16& breakDetails) = 0;
+    virtual void schedulePauseOnNextStatement(const StringView& breakReason, const StringView& breakDetails) = 0;
     virtual void cancelPauseOnNextStatement() = 0;
-    virtual void breakProgram(const String16& breakReason, const String16& breakDetails) = 0;
+    virtual void breakProgram(const StringView& breakReason, const StringView& breakDetails) = 0;
     virtual void setSkipAllPauses(bool) = 0;
     virtual void resume() = 0;
     virtual void stepOver() = 0;
-    virtual std::unique_ptr<blink::protocol::Array<blink::protocol::Debugger::API::SearchMatch>> searchInTextByLines(const String16& text, const String16& query, bool caseSensitive, bool isRegex) = 0;
+    virtual std::unique_ptr<blink::protocol::Array<blink::protocol::Debugger::API::SearchMatch>> searchInTextByLines(const StringView& text, const StringView& query, bool caseSensitive, bool isRegex) = 0;
 
     // Remote objects.
-    virtual std::unique_ptr<blink::protocol::Runtime::API::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName) = 0;
-    virtual bool unwrapObject(ErrorString*, const String16& objectId, v8::Local<v8::Value>*, v8::Local<v8::Context>*, String16* objectGroup) = 0;
-    virtual void releaseObjectGroup(const String16&) = 0;
+    virtual std::unique_ptr<blink::protocol::Runtime::API::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const StringView& groupName) = 0;
+    virtual bool unwrapObject(ErrorString*, const StringView& objectId, v8::Local<v8::Value>*, v8::Local<v8::Context>*, std::unique_ptr<StringBuffer>* objectGroup) = 0;
+    virtual void releaseObjectGroup(const StringView&) = 0;
 };
 
 } // namespace v8_inspector
diff --git a/public/V8StackTrace.h b/public/V8StackTrace.h
index ac68c1b..a7f9b66 100644
--- a/public/V8StackTrace.h
+++ b/public/V8StackTrace.h
@@ -5,7 +5,8 @@
 #ifndef V8StackTrace_h
 #define V8StackTrace_h
 
-#include "platform/inspector_protocol/InspectorProtocol.h"
+#include "platform/v8_inspector/public/StringBuffer.h"
+#include "platform/v8_inspector/public/StringView.h"
 #include "platform/v8_inspector/public/protocol/Runtime.h"
 
 #include <v8.h>
@@ -15,15 +16,15 @@
 class V8StackTrace {
 public:
     virtual bool isEmpty() const = 0;
-    virtual String16 topSourceURL() const = 0;
+    virtual StringView topSourceURL() const = 0;
     virtual int topLineNumber() const = 0;
     virtual int topColumnNumber() const = 0;
-    virtual String16 topScriptId() const = 0;
-    virtual String16 topFunctionName() const = 0;
+    virtual StringView topScriptId() const = 0;
+    virtual StringView topFunctionName() const = 0;
 
     virtual ~V8StackTrace() { }
     virtual std::unique_ptr<blink::protocol::Runtime::API::StackTrace> buildInspectorObject() const = 0;
-    virtual String16 toString() const = 0;
+    virtual std::unique_ptr<StringBuffer> toString() const = 0;
 
     // Safe to pass between threads, drops async chain.
     virtual std::unique_ptr<V8StackTrace> clone() = 0;
diff --git a/v8_inspector.gyp b/v8_inspector.gyp
index dead4f1..892f26c 100644
--- a/v8_inspector.gyp
+++ b/v8_inspector.gyp
@@ -307,11 +307,11 @@
         'V8StringUtil.h',
         'V8ValueCopier.cpp',
         'V8ValueCopier.h',
-        'public/V8EventListenerInfo.h',
+        'public/StringBuffer.h',
+        'public/StringView.h',
         'public/V8ContextInfo.h',
         'public/V8Inspector.h',
         'public/V8InspectorClient.h',
-        'public/V8HeapProfilerAgent.h',
         'public/V8InspectorSession.h',
         'public/V8StackTrace.h',