Browse Source

deps: cherry-pick backports to V8

Included
  acb6779c19
  4e028bd34d
  75fe7739e6
  c22bcd31f0
  49dec1afd8

Not included (cannot be applied cleanly)
  31450fce7c
  2b8a06b323

PR-URL: https://github.com/nodejs/node/pull/3351
Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
v5.x
Michaël Zasso 9 years ago
committed by Ali Ijaz Sheikh
parent
commit
7fb128d8df
  1. 13
      deps/v8/include/v8.h
  2. 41
      deps/v8/src/accessors.cc
  3. 7
      deps/v8/src/api.cc
  4. 29
      deps/v8/src/isolate.cc
  5. 6
      deps/v8/src/isolate.h
  6. 2
      deps/v8/src/objects.h
  7. 30
      deps/v8/test/cctest/test-api.cc
  8. 37
      deps/v8/test/mjsunit/regress/regress-typedarray-length.js
  9. 12
      deps/v8/tools/gen-postmortem-metadata.py

13
deps/v8/include/v8.h

@ -5370,6 +5370,19 @@ class V8_EXPORT Isolate {
*/
static Isolate* GetCurrent();
/**
* Custom callback used by embedders to help V8 determine if it should abort
* when it throws and no internal handler is predicted to catch the
* exception. If --abort-on-uncaught-exception is used on the command line,
* then V8 will abort if either:
* - no custom callback is set.
* - the custom callback set returns true.
* Otherwise, the custom callback will not be called and V8 will not abort.
*/
typedef bool (*AbortOnUncaughtExceptionCallback)(Isolate*);
void SetAbortOnUncaughtExceptionCallback(
AbortOnUncaughtExceptionCallback callback);
/**
* Methods below this point require holding a lock (using Locker) in
* a multi-threaded environment.

41
deps/v8/src/accessors.cc

@ -99,22 +99,37 @@ bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
Isolate* isolate = name->GetIsolate();
switch (map->instance_type()) {
case JS_TYPED_ARRAY_TYPE:
// %TypedArray%.prototype is non-configurable, and so are the following
// named properties on %TypedArray%.prototype, so we can directly inline
// the field-load for typed array maps that still use their
// %TypedArray%.prototype.
if (JSFunction::cast(map->GetConstructor())->prototype() !=
map->prototype()) {
case JS_TYPED_ARRAY_TYPE: {
if (!CheckForName(name, isolate->factory()->length_string(),
JSTypedArray::kLengthOffset, object_offset) &&
!CheckForName(name, isolate->factory()->byte_length_string(),
JSTypedArray::kByteLengthOffset, object_offset) &&
!CheckForName(name, isolate->factory()->byte_offset_string(),
JSTypedArray::kByteOffsetOffset, object_offset)) {
return false;
}
return CheckForName(name, isolate->factory()->length_string(),
JSTypedArray::kLengthOffset, object_offset) ||
CheckForName(name, isolate->factory()->byte_length_string(),
JSTypedArray::kByteLengthOffset, object_offset) ||
CheckForName(name, isolate->factory()->byte_offset_string(),
JSTypedArray::kByteOffsetOffset, object_offset);
if (map->is_dictionary_map()) return false;
// Check if the property is overridden on the instance.
DescriptorArray* descriptors = map->instance_descriptors();
int descriptor = descriptors->SearchWithCache(*name, *map);
if (descriptor != DescriptorArray::kNotFound) return false;
Handle<Object> proto = Handle<Object>(map->prototype(), isolate);
if (!proto->IsJSReceiver()) return false;
// Check if the property is defined in the prototype chain.
LookupIterator it(proto, name);
if (!it.IsFound()) return false;
Object* original_proto =
JSFunction::cast(map->GetConstructor())->prototype();
// Property is not configurable. It is enough to verify that
// the holder is the same.
return *it.GetHolder<Object>() == original_proto;
}
case JS_DATA_VIEW_TYPE:
return CheckForName(name, isolate->factory()->byte_length_string(),
JSDataView::kByteLengthOffset, object_offset) ||

7
deps/v8/src/api.cc

@ -7160,6 +7160,13 @@ void Isolate::Exit() {
}
void Isolate::SetAbortOnUncaughtExceptionCallback(
AbortOnUncaughtExceptionCallback callback) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->SetAbortOnUncaughtExceptionCallback(callback);
}
Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
Isolate* isolate,
Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)

29
deps/v8/src/isolate.cc

@ -1013,13 +1013,21 @@ Object* Isolate::Throw(Object* exception, MessageLocation* location) {
Handle<Object> message_obj = CreateMessage(exception_handle, location);
thread_local_top()->pending_message_obj_ = *message_obj;
// If the abort-on-uncaught-exception flag is specified, abort on any
// exception not caught by JavaScript, even when an external handler is
// present. This flag is intended for use by JavaScript developers, so
// print a user-friendly stack trace (not an internal one).
// For any exception not caught by JavaScript, even when an external
// handler is present:
// If the abort-on-uncaught-exception flag is specified, and if the
// embedder didn't specify a custom uncaught exception callback,
// or if the custom callback determined that V8 should abort, then
// abort.
if (FLAG_abort_on_uncaught_exception &&
PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) {
FLAG_abort_on_uncaught_exception = false; // Prevent endless recursion.
PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT &&
(!abort_on_uncaught_exception_callback_ ||
abort_on_uncaught_exception_callback_(
reinterpret_cast<v8::Isolate*>(this)))) {
// Prevent endless recursion.
FLAG_abort_on_uncaught_exception = false;
// This flag is intended for use by JavaScript developers, so
// print a user-friendly stack trace (not an internal one).
PrintF(stderr, "%s\n\nFROM\n",
MessageHandler::GetLocalizedMessage(this, message_obj).get());
PrintCurrentStackTrace(stderr);
@ -1607,6 +1615,12 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
}
void Isolate::SetAbortOnUncaughtExceptionCallback(
v8::Isolate::AbortOnUncaughtExceptionCallback callback) {
abort_on_uncaught_exception_callback_ = callback;
}
Handle<Context> Isolate::native_context() {
return handle(context()->native_context());
}
@ -1774,7 +1788,8 @@ Isolate::Isolate(bool enable_serializer)
next_unique_sfi_id_(0),
#endif
use_counter_callback_(NULL),
basic_block_profiler_(NULL) {
basic_block_profiler_(NULL),
abort_on_uncaught_exception_callback_(NULL) {
{
base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
CHECK(thread_data_table_);

6
deps/v8/src/isolate.h

@ -698,6 +698,9 @@ class Isolate {
int frame_limit,
StackTrace::StackTraceOptions options);
void SetAbortOnUncaughtExceptionCallback(
v8::Isolate::AbortOnUncaughtExceptionCallback callback);
enum PrintStackMode { kPrintStackConcise, kPrintStackVerbose };
void PrintCurrentStackTrace(FILE* out);
void PrintStack(StringStream* accumulator,
@ -1366,6 +1369,9 @@ class Isolate {
std::set<Cancelable*> cancelable_tasks_;
v8::Isolate::AbortOnUncaughtExceptionCallback
abort_on_uncaught_exception_callback_;
friend class ExecutionAccess;
friend class HandleScopeImplementer;
friend class OptimizingCompileDispatcher;

2
deps/v8/src/objects.h

@ -3932,7 +3932,6 @@ class ScopeInfo : public FixedArray {
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(FIELD_ACCESSORS)
#undef FIELD_ACCESSORS
private:
enum {
#define DECL_INDEX(name) k##name,
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(DECL_INDEX)
@ -3940,6 +3939,7 @@ class ScopeInfo : public FixedArray {
kVariablePartIndex
};
private:
// The layout of the variable part of a ScopeInfo is as follows:
// 1. ParameterEntries:
// This part stores the names of the parameters for function scopes. One

30
deps/v8/test/cctest/test-api.cc

@ -21826,4 +21826,34 @@ TEST(EstimatedContextSize) {
v8::HandleScope scope(isolate);
LocalContext env;
CHECK(50000 < env->EstimatedSize());
static int nb_uncaught_exception_callback_calls = 0;
bool NoAbortOnUncaughtException(v8::Isolate* isolate) {
++nb_uncaught_exception_callback_calls;
return false;
}
TEST(AbortOnUncaughtExceptionNoAbort) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate);
LocalContext env(NULL, global_template);
i::FLAG_abort_on_uncaught_exception = true;
isolate->SetAbortOnUncaughtExceptionCallback(NoAbortOnUncaughtException);
CompileRun("function boom() { throw new Error(\"boom\") }");
v8::Local<v8::Object> global_object = env->Global();
v8::Local<v8::Function> foo =
v8::Local<v8::Function>::Cast(global_object->Get(v8_str("boom")));
foo->Call(global_object, 0, NULL);
CHECK_EQ(1, nb_uncaught_exception_callback_calls);
}

37
deps/v8/test/mjsunit/regress/regress-typedarray-length.js

@ -71,6 +71,43 @@ assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
})();
(function() {
"use strict";
class MyTypedArray extends Int32Array {
constructor(length) {
super(length);
}
}
a = new MyTypedArray(1024);
get = function(a) {
return a.length;
}
assertEquals(1024, get(a));
assertEquals(1024, get(a));
assertEquals(1024, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(1024, get(a));
})();
(function() {
"use strict";
var a = new Uint8Array(4);
Object.defineProperty(a, "length", {get: function() { return "blah"; }});
get = function(a) {
return a.length;
}
assertEquals("blah", get(a));
assertEquals("blah", get(a));
assertEquals("blah", get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals("blah", get(a));
})();
// Ensure we cannot delete length, byteOffset, byteLength.
assertTrue(Int32Array.prototype.hasOwnProperty("length"));
assertTrue(Int32Array.prototype.hasOwnProperty("byteOffset"));

12
deps/v8/tools/gen-postmortem-metadata.py

@ -132,6 +132,15 @@ consts_misc = [
'value': 'JavaScriptFrameConstants::kFunctionOffset' },
{ 'name': 'off_fp_args',
'value': 'JavaScriptFrameConstants::kLastParameterOffset' },
{ 'name': 'scopeinfo_idx_nparams',
'value': 'ScopeInfo::kParameterCount' },
{ 'name': 'scopeinfo_idx_nstacklocals',
'value': 'ScopeInfo::kStackLocalCount' },
{ 'name': 'scopeinfo_idx_ncontextlocals',
'value': 'ScopeInfo::kContextLocalCount' },
{ 'name': 'scopeinfo_idx_first_vars',
'value': 'ScopeInfo::kVariablePartIndex' },
];
#
@ -141,12 +150,13 @@ extras_accessors = [
'HeapObject, map, Map, kMapOffset',
'JSObject, elements, Object, kElementsOffset',
'FixedArray, data, uintptr_t, kHeaderSize',
'JSTypedArray, length, Object, kLengthOffset',
'Map, instance_attributes, int, kInstanceAttributesOffset',
'Map, inobject_properties_of_constructor_function_index_offset, int, kInObjectPropertiesOrConstructorFunctionIndexOffset',
'Map, instance_size, int, kInstanceSizeOffset',
'Map, bit_field, char, kBitFieldOffset',
'Map, bit_field2, char, kBitField2Offset',
'Map, bit_field3, SMI, kBitField3Offset',
'Map, bit_field3, int, kBitField3Offset',
'Map, prototype, Object, kPrototypeOffset',
'NameDictionaryShape, prefix_size, int, kPrefixSize',
'NameDictionaryShape, entry_size, int, kEntrySize',

Loading…
Cancel
Save