Upgrade V8 to 8.8.278.14
Bug: 162604069
Bug: 167389063
Test: gts-tradefed run gts-dev --module GtsGmscoreHostTestCases
--test com.google.android.gts.devicepolicy.DeviceOwnerTest#testProxyPacProxyTest
Test: m -j proxy_resolver_v8_unittest && adb sync && adb shell \
/data/nativetest/proxy_resolver_v8_unittest/proxy_resolver_v8_unittest
Merged-In: Ifb09923b9d7f6d8990fb062d7dc0294edf2c098e
Change-Id: Ifb09923b9d7f6d8990fb062d7dc0294edf2c098e
(cherry picked from commit 9580a23bc5b8874a0979001d3595d027cbb68128)
diff --git a/src/builtins/builtins-api.cc b/src/builtins/builtins-api.cc
index eb34638..e42760d 100644
--- a/src/builtins/builtins-api.cc
+++ b/src/builtins/builtins-api.cc
@@ -2,15 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/api/api-arguments-inl.h"
+#include "src/api/api-natives.h"
+#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
-
-#include "src/api-arguments.h"
-#include "src/api-natives.h"
-#include "src/builtins/builtins-utils.h"
-#include "src/counters.h"
-#include "src/log.h"
-#include "src/objects-inl.h"
-#include "src/prototype.h"
+#include "src/logging/counters.h"
+#include "src/logging/log.h"
+#include "src/objects/objects-inl.h"
+#include "src/objects/prototype.h"
+#include "src/objects/templates.h"
+#include "src/objects/visitors.h"
namespace v8 {
namespace internal {
@@ -20,95 +21,94 @@
// Returns the holder JSObject if the function can legally be called with this
// receiver. Returns nullptr if the call is illegal.
// TODO(dcarney): CallOptimization duplicates this logic, merge.
-JSObject* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info,
- JSObject* receiver) {
- Object* recv_type = info->signature();
+JSReceiver GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo info,
+ JSReceiver receiver) {
+ Object recv_type = info.signature();
// No signature, return holder.
- if (!recv_type->IsFunctionTemplateInfo()) return receiver;
- FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
+ if (!recv_type.IsFunctionTemplateInfo()) return receiver;
+ // A Proxy cannot have been created from the signature template.
+ if (!receiver.IsJSObject()) return JSReceiver();
- // Check the receiver. Fast path for receivers with no hidden prototypes.
- if (signature->IsTemplateFor(receiver)) return receiver;
- if (!receiver->map()->has_hidden_prototype()) return nullptr;
- for (PrototypeIterator iter(isolate, receiver, kStartAtPrototype,
- PrototypeIterator::END_AT_NON_HIDDEN);
- !iter.IsAtEnd(); iter.Advance()) {
- JSObject* current = iter.GetCurrent<JSObject>();
- if (signature->IsTemplateFor(current)) return current;
+ JSObject js_obj_receiver = JSObject::cast(receiver);
+ FunctionTemplateInfo signature = FunctionTemplateInfo::cast(recv_type);
+
+ // Check the receiver.
+ if (signature.IsTemplateFor(js_obj_receiver)) return receiver;
+
+ // The JSGlobalProxy might have a hidden prototype.
+ if (V8_UNLIKELY(js_obj_receiver.IsJSGlobalProxy())) {
+ HeapObject prototype = js_obj_receiver.map().prototype();
+ if (!prototype.IsNull(isolate)) {
+ JSObject js_obj_prototype = JSObject::cast(prototype);
+ if (signature.IsTemplateFor(js_obj_prototype)) return js_obj_prototype;
+ }
}
- return nullptr;
+ return JSReceiver();
}
template <bool is_construct>
-MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
+V8_WARN_UNUSED_RESULT MaybeHandle<Object> HandleApiCallHelper(
Isolate* isolate, Handle<HeapObject> function,
Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data,
Handle<Object> receiver, BuiltinArguments args) {
- Handle<JSObject> js_receiver;
- JSObject* raw_holder;
+ Handle<JSReceiver> js_receiver;
+ JSReceiver raw_holder;
if (is_construct) {
DCHECK(args.receiver()->IsTheHole(isolate));
- if (fun_data->instance_template()->IsUndefined(isolate)) {
+ if (fun_data->GetInstanceTemplate().IsUndefined(isolate)) {
v8::Local<ObjectTemplate> templ =
ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate),
ToApiHandle<v8::FunctionTemplate>(fun_data));
- fun_data->set_instance_template(*Utils::OpenHandle(*templ));
+ FunctionTemplateInfo::SetInstanceTemplate(isolate, fun_data,
+ Utils::OpenHandle(*templ));
}
Handle<ObjectTemplateInfo> instance_template(
- ObjectTemplateInfo::cast(fun_data->instance_template()), isolate);
+ ObjectTemplateInfo::cast(fun_data->GetInstanceTemplate()), isolate);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, js_receiver,
- ApiNatives::InstantiateObject(instance_template,
+ ApiNatives::InstantiateObject(isolate, instance_template,
Handle<JSReceiver>::cast(new_target)),
Object);
- args[0] = *js_receiver;
+ args.set_at(0, *js_receiver);
DCHECK_EQ(*js_receiver, *args.receiver());
raw_holder = *js_receiver;
} else {
DCHECK(receiver->IsJSReceiver());
-
- if (!receiver->IsJSObject()) {
- // This function cannot be called with the given receiver. Abort!
- THROW_NEW_ERROR(
- isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
- }
-
- js_receiver = Handle<JSObject>::cast(receiver);
+ js_receiver = Handle<JSReceiver>::cast(receiver);
if (!fun_data->accept_any_receiver() &&
- js_receiver->IsAccessCheckNeeded() &&
- !isolate->MayAccess(handle(isolate->context()), js_receiver)) {
- isolate->ReportFailedAccessCheck(js_receiver);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return isolate->factory()->undefined_value();
+ js_receiver->IsAccessCheckNeeded()) {
+ // Proxies never need access checks.
+ DCHECK(js_receiver->IsJSObject());
+ Handle<JSObject> js_obj_receiver = Handle<JSObject>::cast(js_receiver);
+ if (!isolate->MayAccess(handle(isolate->context(), isolate),
+ js_obj_receiver)) {
+ isolate->ReportFailedAccessCheck(js_obj_receiver);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ return isolate->factory()->undefined_value();
+ }
}
raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver);
- if (raw_holder == nullptr) {
+ if (raw_holder.is_null()) {
// This function cannot be called with the given receiver. Abort!
THROW_NEW_ERROR(
isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
}
}
- Object* raw_call_data = fun_data->call_code();
- if (!raw_call_data->IsUndefined(isolate)) {
- DCHECK(raw_call_data->IsCallHandlerInfo());
- CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
- Object* callback_obj = call_data->callback();
- v8::FunctionCallback callback =
- v8::ToCData<v8::FunctionCallback>(callback_obj);
- Object* data_obj = call_data->data();
+ Object raw_call_data = fun_data->call_code(kAcquireLoad);
+ if (!raw_call_data.IsUndefined(isolate)) {
+ DCHECK(raw_call_data.IsCallHandlerInfo());
+ CallHandlerInfo call_data = CallHandlerInfo::cast(raw_call_data);
+ Object data_obj = call_data.data();
- LOG(isolate, ApiObjectAccess("call", JSObject::cast(*js_receiver)));
-
- FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder,
- *new_target, &args[0] - 1,
- args.length() - 1);
-
- Handle<Object> result = custom.Call(callback);
+ FunctionCallbackArguments custom(
+ isolate, data_obj, *function, raw_holder, *new_target,
+ args.address_of_first_argument(), args.length() - 1);
+ Handle<Object> result = custom.Call(call_data);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.is_null()) {
@@ -117,7 +117,8 @@
}
// Rebox the result.
result->VerifyApiCallResultType();
- if (!is_construct || result->IsJSObject()) return handle(*result, isolate);
+ if (!is_construct || result->IsJSReceiver())
+ return handle(*result, isolate);
}
return js_receiver;
@@ -130,7 +131,7 @@
Handle<JSFunction> function = args.target();
Handle<Object> receiver = args.receiver();
Handle<HeapObject> new_target = args.new_target();
- Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(),
+ Handle<FunctionTemplateInfo> fun_data(function->shared().get_api_func_data(),
isolate);
if (new_target->IsJSReceiver()) {
RETURN_RESULT_OR_FAILURE(
@@ -147,12 +148,13 @@
class RelocatableArguments : public BuiltinArguments, public Relocatable {
public:
- RelocatableArguments(Isolate* isolate, int length, Object** arguments)
+ RelocatableArguments(Isolate* isolate, int length, Address* arguments)
: BuiltinArguments(length, arguments), Relocatable(isolate) {}
- virtual inline void IterateInstance(ObjectVisitor* v) {
+ inline void IterateInstance(RootVisitor* v) override {
if (length() == 0) return;
- v->VisitPointers(lowest_address(), highest_address() + 1);
+ v->VisitRootPointers(Root::kRelocatable, nullptr, first_slot(),
+ last_slot() + 1);
}
private:
@@ -167,45 +169,53 @@
Handle<Object> receiver,
int argc, Handle<Object> args[],
Handle<HeapObject> new_target) {
+ RuntimeCallTimerScope timer(isolate,
+ RuntimeCallCounterId::kInvokeApiFunction);
DCHECK(function->IsFunctionTemplateInfo() ||
(function->IsJSFunction() &&
- JSFunction::cast(*function)->shared()->IsApiFunction()));
+ JSFunction::cast(*function).shared().IsApiFunction()));
// Do proper receiver conversion for non-strict mode api functions.
if (!is_construct && !receiver->IsJSReceiver()) {
if (function->IsFunctionTemplateInfo() ||
- is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) {
+ is_sloppy(JSFunction::cast(*function).shared().language_mode())) {
ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
Object::ConvertReceiver(isolate, receiver),
Object);
}
}
+ // We assume that all lazy accessor pairs have been instantiated when setting
+ // a break point on any API function.
+ DCHECK_IMPLIES(function->IsFunctionTemplateInfo(),
+ !Handle<FunctionTemplateInfo>::cast(function)->BreakAtEntry());
+
Handle<FunctionTemplateInfo> fun_data =
function->IsFunctionTemplateInfo()
? Handle<FunctionTemplateInfo>::cast(function)
- : handle(JSFunction::cast(*function)->shared()->get_api_func_data(),
+ : handle(JSFunction::cast(*function).shared().get_api_func_data(),
isolate);
// Construct BuiltinArguments object:
// new target, function, arguments reversed, receiver.
const int kBufferSize = 32;
- Object* small_argv[kBufferSize];
- Object** argv;
+ Address small_argv[kBufferSize];
+ Address* argv;
const int frame_argc = argc + BuiltinArguments::kNumExtraArgsWithReceiver;
if (frame_argc <= kBufferSize) {
argv = small_argv;
} else {
- argv = new Object*[frame_argc];
+ argv = new Address[frame_argc];
}
- int cursor = frame_argc - 1;
- argv[cursor--] = *receiver;
+ argv[BuiltinArguments::kNewTargetOffset] = new_target->ptr();
+ argv[BuiltinArguments::kTargetOffset] = function->ptr();
+ argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc).ptr();
+ argv[BuiltinArguments::kPaddingOffset] =
+ ReadOnlyRoots(isolate).the_hole_value().ptr();
+ int cursor = BuiltinArguments::kNumExtraArgs;
+ argv[cursor++] = receiver->ptr();
for (int i = 0; i < argc; ++i) {
- argv[cursor--] = *args[i];
+ argv[cursor++] = args[i]->ptr();
}
- DCHECK(cursor == BuiltinArguments::kArgcOffset);
- argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc);
- argv[BuiltinArguments::kTargetOffset] = *function;
- argv[BuiltinArguments::kNewTargetOffset] = *new_target;
MaybeHandle<Object> result;
{
RelocatableArguments arguments(isolate, frame_argc, &argv[frame_argc - 1]);
@@ -224,15 +234,15 @@
// Helper function to handle calls to non-function objects created through the
// API. The object can be called as either a constructor (using new) or just as
// a function (without new).
-MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
+V8_WARN_UNUSED_RESULT static Object HandleApiCallAsFunctionOrConstructor(
Isolate* isolate, bool is_construct_call, BuiltinArguments args) {
Handle<Object> receiver = args.receiver();
// Get the object called.
- JSObject* obj = JSObject::cast(*receiver);
+ JSObject obj = JSObject::cast(*receiver);
// Set the new target.
- HeapObject* new_target;
+ HeapObject new_target;
if (is_construct_call) {
// TODO(adamk): This should be passed through in args instead of
// being patched in here. We need to set a non-undefined value
@@ -240,37 +250,30 @@
// right answer.
new_target = obj;
} else {
- new_target = isolate->heap()->undefined_value();
+ new_target = ReadOnlyRoots(isolate).undefined_value();
}
// Get the invocation callback from the function descriptor that was
// used to create the called object.
- DCHECK(obj->map()->is_callable());
- JSFunction* constructor = JSFunction::cast(obj->map()->GetConstructor());
- // TODO(ishell): turn this back to a DCHECK.
- CHECK(constructor->shared()->IsApiFunction());
- Object* handler =
- constructor->shared()->get_api_func_data()->instance_call_handler();
- DCHECK(!handler->IsUndefined(isolate));
- // TODO(ishell): remove this debugging code.
- CHECK(handler->IsCallHandlerInfo());
- CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
- Object* callback_obj = call_data->callback();
- v8::FunctionCallback callback =
- v8::ToCData<v8::FunctionCallback>(callback_obj);
+ DCHECK(obj.map().is_callable());
+ JSFunction constructor = JSFunction::cast(obj.map().GetConstructor());
+ DCHECK(constructor.shared().IsApiFunction());
+ Object handler =
+ constructor.shared().get_api_func_data().GetInstanceCallHandler();
+ DCHECK(!handler.IsUndefined(isolate));
+ CallHandlerInfo call_data = CallHandlerInfo::cast(handler);
// Get the data for the call and perform the callback.
- Object* result;
+ Object result;
{
HandleScope scope(isolate);
LOG(isolate, ApiObjectAccess("call non-function", obj));
-
- FunctionCallbackArguments custom(isolate, call_data->data(), constructor,
- obj, new_target, &args[0] - 1,
- args.length() - 1);
- Handle<Object> result_handle = custom.Call(callback);
+ FunctionCallbackArguments custom(
+ isolate, call_data.data(), constructor, obj, new_target,
+ args.address_of_first_argument(), args.length() - 1);
+ Handle<Object> result_handle = custom.Call(call_data);
if (result_handle.is_null()) {
- result = isolate->heap()->undefined_value();
+ result = ReadOnlyRoots(isolate).undefined_value();
} else {
result = *result_handle;
}