Version 3.2.5
Fixed build with Irregexp interpreter (issue 1266).
Added Crankshaft support for external arrays.
Fixed two potential crash bugs.
git-svn-id: http://v8.googlecode.com/svn/trunk@7385 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/.gitignore b/.gitignore
index db57d1b..c6b6047 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@
/test/es5conform/data/
/test/mozilla/data/
/test/sputnik/sputniktests/
+/test/test262/data/
/tools/oom_dump/oom_dump
/tools/oom_dump/oom_dump.o
/tools/visual_studio/Debug
diff --git a/ChangeLog b/ChangeLog
index 4ccf6fc..ce4d81e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-03-28: Version 3.2.5
+
+ Fixed build with Irregexp interpreter (issue 1266).
+
+ Added Crankshaft support for external arrays.
+
+ Fixed two potential crash bugs.
+
+
2011-03-23: Version 3.2.4
Added isolates which allows several V8 instances in the same process.
diff --git a/SConstruct b/SConstruct
index b432f5e..76a4e03 100644
--- a/SConstruct
+++ b/SConstruct
@@ -128,6 +128,9 @@
'inspector:on': {
'CPPDEFINES': ['INSPECTOR'],
},
+ 'fasttls:on': {
+ 'CPPDEFINES': ['V8_FAST_TLS'],
+ },
'liveobjectlist:on': {
'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR',
'LIVE_OBJECT_LIST', 'OBJECT_PRINT'],
@@ -785,6 +788,12 @@
'default': 'off',
'help': 'enable the disassembler to inspect generated code'
},
+ 'fasttls': {
+ 'values': ['on', 'off'],
+ 'default': 'on',
+ 'help': 'enable fast thread local storage support '
+ '(if available on the current architecture/platform)'
+ },
'sourcesignatures': {
'values': ['MD5', 'timestamp'],
'default': 'MD5',
diff --git a/samples/shell.cc b/samples/shell.cc
index a65d10a..47de846 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -36,8 +36,8 @@
// When building with V8 in a shared library we cannot use functions which
// is not explicitly a part of the public V8 API. This extensive use of
// #ifndef USING_V8_SHARED/#endif is a hack until we can resolve whether to
-// still use the shell sample for testing or change to use the and the
-// developer shell d8 TODO(1272).
+// still use the shell sample for testing or change to use the developer
+// shell d8 TODO(1272).
#ifndef USING_V8_SHARED
#include "../src/v8.h"
#endif // USING_V8_SHARED
@@ -73,7 +73,7 @@
class SourceGroup {
public:
- SourceGroup() :
+ SourceGroup() :
#ifndef USING_V8_SHARED
next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
diff --git a/src/api.cc b/src/api.cc
index 32381dc..dcf8e17 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -55,45 +55,45 @@
// TODO(isolates): avoid repeated TLS reads in function prologues.
#ifdef ENABLE_VMSTATE_TRACKING
-#define ENTER_V8 \
- ASSERT(i::Isolate::Current()->IsInitialized()); \
- i::VMState __state__(i::Isolate::Current(), i::OTHER)
-#define LEAVE_V8 \
- i::VMState __state__(i::Isolate::Current(), i::EXTERNAL)
+#define ENTER_V8(isolate) \
+ ASSERT((isolate)->IsInitialized()); \
+ i::VMState __state__((isolate), i::OTHER)
+#define LEAVE_V8(isolate) \
+ i::VMState __state__((isolate), i::EXTERNAL)
#else
-#define ENTER_V8 ((void) 0)
-#define LEAVE_V8 ((void) 0)
+#define ENTER_V8(isolate) ((void) 0)
+#define LEAVE_V8(isolate) ((void) 0)
#endif
namespace v8 {
#define ON_BAILOUT(isolate, location, code) \
if (IsDeadCheck(isolate, location) || \
- v8::V8::IsExecutionTerminating()) { \
+ IsExecutionTerminatingCheck(isolate)) { \
code; \
UNREACHABLE(); \
}
-#define EXCEPTION_PREAMBLE() \
- i::Isolate::Current()->handle_scope_implementer()->IncrementCallDepth(); \
- ASSERT(!i::Isolate::Current()->external_caught_exception()); \
+#define EXCEPTION_PREAMBLE(isolate) \
+ (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
+ ASSERT(!(isolate)->external_caught_exception()); \
bool has_pending_exception = false
-#define EXCEPTION_BAILOUT_CHECK(value) \
+#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
do { \
i::HandleScopeImplementer* handle_scope_implementer = \
- isolate->handle_scope_implementer(); \
+ (isolate)->handle_scope_implementer(); \
handle_scope_implementer->DecrementCallDepth(); \
if (has_pending_exception) { \
if (handle_scope_implementer->CallDepthIsZero() && \
- i::Isolate::Current()->is_out_of_memory()) { \
+ (isolate)->is_out_of_memory()) { \
if (!handle_scope_implementer->ignore_out_of_memory()) \
i::V8::FatalProcessOutOfMemory(NULL); \
} \
bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
- i::Isolate::Current()->OptionalRescheduleException(call_depth_is_zero); \
+ (isolate)->OptionalRescheduleException(call_depth_is_zero); \
return value; \
} \
} while (false)
@@ -191,11 +191,12 @@
heap_stats.os_error = &os_error;
int end_marker;
heap_stats.end_marker = &end_marker;
- HEAP->RecordStats(&heap_stats, take_snapshot);
+ i::Isolate* isolate = i::Isolate::Current();
+ isolate->heap()->RecordStats(&heap_stats, take_snapshot);
i::V8::SetFatalError();
FatalErrorCallback callback = GetFatalErrorHandler();
{
- LEAVE_V8;
+ LEAVE_V8(isolate);
callback(location, "Allocation failed - process out of memory");
}
// If the callback returns, we stop execution.
@@ -255,6 +256,16 @@
}
+static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
+ if (!isolate->IsInitialized()) return false;
+ if (isolate->has_scheduled_exception()) {
+ return isolate->scheduled_exception() ==
+ isolate->heap()->termination_exception();
+ }
+ return false;
+}
+
+
static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
}
@@ -282,11 +293,6 @@
return ApiCheck(InitializeHelper(), location, "Error initializing V8");
}
-static inline bool EnsureInitialized(const char* location) {
- i::Isolate* isolate = i::Isolate::UncheckedCurrent();
- return EnsureInitializedForIsolate(isolate, location);
-}
-
// Some initializing API functions are called early and may be
// called on a thread different from static initializer thread.
// If Isolate API is used, Isolate::Enter() will initialize TLS so
@@ -319,32 +325,6 @@
#endif
-v8::Handle<v8::Primitive> ImplementationUtilities::Undefined() {
- if (!EnsureInitialized("v8::Undefined()")) return v8::Handle<v8::Primitive>();
- return v8::Handle<Primitive>(ToApi<Primitive>(FACTORY->undefined_value()));
-}
-
-
-v8::Handle<v8::Primitive> ImplementationUtilities::Null() {
- i::Isolate* isolate = i::Isolate::UncheckedCurrent();
- if (!EnsureInitializedForIsolate(isolate, "v8::Null()"))
- return v8::Handle<v8::Primitive>();
- return v8::Handle<Primitive>(
- ToApi<Primitive>(isolate->factory()->null_value()));
-}
-
-
-v8::Handle<v8::Boolean> ImplementationUtilities::True() {
- if (!EnsureInitialized("v8::True()")) return v8::Handle<v8::Boolean>();
- return v8::Handle<v8::Boolean>(ToApi<Boolean>(FACTORY->true_value()));
-}
-
-
-v8::Handle<v8::Boolean> ImplementationUtilities::False() {
- if (!EnsureInitialized("v8::False()")) return v8::Handle<v8::Boolean>();
- return v8::Handle<v8::Boolean>(ToApi<Boolean>(FACTORY->false_value()));
-}
-
void V8::SetFlagsFromString(const char* str, int length) {
i::FlagList::SetFlagsFromString(str, length);
}
@@ -360,11 +340,11 @@
if (IsDeadCheck(isolate, "v8::ThrowException()")) {
return v8::Handle<Value>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
// If we're passed an empty handle, we throw an undefined exception
// to deal more gracefully with out of memory situations.
if (value.IsEmpty()) {
- isolate->ScheduleThrow(HEAP->undefined_value());
+ isolate->ScheduleThrow(isolate->heap()->undefined_value());
} else {
isolate->ScheduleThrow(*Utils::OpenHandle(*value));
}
@@ -404,29 +384,41 @@
v8::Handle<Primitive> Undefined() {
i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "Undefined");
- return ImplementationUtilities::Undefined();
+ if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
+ return v8::Handle<v8::Primitive>();
+ }
+ return v8::Handle<Primitive>(ToApi<Primitive>(
+ isolate->factory()->undefined_value()));
}
v8::Handle<Primitive> Null() {
i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "Null");
- return ImplementationUtilities::Null();
+ if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
+ return v8::Handle<v8::Primitive>();
+ }
+ return v8::Handle<Primitive>(
+ ToApi<Primitive>(isolate->factory()->null_value()));
}
v8::Handle<Boolean> True() {
i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "True");
- return ImplementationUtilities::True();
+ if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
+ return v8::Handle<Boolean>();
+ }
+ return v8::Handle<Boolean>(
+ ToApi<Boolean>(isolate->factory()->true_value()));
}
v8::Handle<Boolean> False() {
i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "False");
- return ImplementationUtilities::False();
+ if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
+ return v8::Handle<Boolean>();
+ }
+ return v8::Handle<Boolean>(
+ ToApi<Boolean>(isolate->factory()->false_value()));
}
@@ -550,7 +542,8 @@
int HandleScope::NumberOfHandles() {
- EnsureInitialized("HandleScope::NumberOfHandles");
+ EnsureInitializedForIsolate(
+ i::Isolate::Current(), "HandleScope::NumberOfHandles");
return i::HandleScope::NumberOfHandles();
}
@@ -571,7 +564,8 @@
// TODO(isolates): Context should have a pointer to isolate.
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
+
i::Handle<i::Context> env = Utils::OpenHandle(this);
isolate->handle_scope_implementer()->EnterContext(env);
@@ -602,7 +596,7 @@
// TODO(isolates): Context should have a pointer to isolate.
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
{
i::HandleScope scope(isolate);
i::Handle<i::Context> env = Utils::OpenHandle(this);
@@ -621,7 +615,7 @@
if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
return v8::Local<Value>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* raw_result = NULL;
{
i::HandleScope scope(isolate);
@@ -673,10 +667,11 @@
// NeanderObject constructor. When you add one to the site calling the
// constructor you should check that you ensured the VM was not dead first.
NeanderObject::NeanderObject(int size) {
- EnsureInitialized("v8::Nowhere");
- ENTER_V8;
- value_ = FACTORY->NewNeanderObject();
- i::Handle<i::FixedArray> elements = FACTORY->NewFixedArray(size);
+ i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate, "v8::Nowhere");
+ ENTER_V8(isolate);
+ value_ = isolate->factory()->NewNeanderObject();
+ i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
value_->set_elements(*elements);
}
@@ -740,7 +735,7 @@
v8::PropertyAttribute attribute) {
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
if (list->IsUndefined()) {
@@ -763,11 +758,11 @@
Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
return Local<ObjectTemplate>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
if (result->IsUndefined()) {
result = Utils::OpenHandle(*ObjectTemplate::New());
@@ -778,9 +773,9 @@
void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
}
@@ -790,7 +785,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
LOG_API(isolate, "FunctionTemplate::New");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
i::Handle<i::FunctionTemplateInfo> obj =
@@ -817,7 +812,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
LOG_API(isolate, "Signature::New");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
i::Handle<i::SignatureInfo> obj =
@@ -845,7 +840,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
LOG_API(isolate, "TypeSwitch::New");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
for (int i = 0; i < argc; i++)
vector->set(i, *Utils::OpenHandle(*types[i]));
@@ -880,9 +875,9 @@
void FunctionTemplate::SetCallHandler(InvocationCallback callback,
v8::Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
@@ -924,12 +919,12 @@
v8::Handle<Value> data,
v8::AccessControl settings,
v8::PropertyAttribute attributes) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate,
"v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
@@ -946,11 +941,11 @@
Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
|| EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
return Local<ObjectTemplate>();
- ENTER_V8;
+ ENTER_V8(isolate);
if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
Local<ObjectTemplate> templ =
ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
@@ -963,19 +958,19 @@
void FunctionTemplate::SetClassName(Handle<String> name) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
}
void FunctionTemplate::SetHiddenPrototype(bool value) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
Utils::OpenHandle(this)->set_hidden_prototype(value);
}
@@ -987,12 +982,12 @@
NamedPropertyDeleter remover,
NamedPropertyEnumerator enumerator,
Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate,
"v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
@@ -1018,12 +1013,12 @@
IndexedPropertyDeleter remover,
IndexedPropertyEnumerator enumerator,
Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate,
"v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
@@ -1045,12 +1040,12 @@
void FunctionTemplate::SetInstanceCallAsFunctionHandler(
InvocationCallback callback,
Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate,
"v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
@@ -1079,9 +1074,9 @@
}
EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
LOG_API(isolate, "ObjectTemplate::New");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
+ isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
i::Handle<i::ObjectTemplateInfo> obj =
i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
@@ -1110,9 +1105,9 @@
v8::Handle<Value> data,
AccessControl settings,
PropertyAttribute attribute) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
EnsureConstructor(this);
i::FunctionTemplateInfo* constructor =
@@ -1133,12 +1128,12 @@
NamedPropertyDeleter remover,
NamedPropertyEnumerator enumerator,
Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
return;
}
- ENTER_V8;
- HandleScope scope;
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
EnsureConstructor(this);
i::FunctionTemplateInfo* constructor =
i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
@@ -1153,9 +1148,9 @@
void ObjectTemplate::MarkAsUndetectable() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
EnsureConstructor(this);
i::FunctionTemplateInfo* constructor =
@@ -1170,11 +1165,11 @@
IndexedSecurityCallback indexed_callback,
Handle<Value> data,
bool turned_on_by_default) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
EnsureConstructor(this);
@@ -1204,11 +1199,11 @@
IndexedPropertyDeleter remover,
IndexedPropertyEnumerator enumerator,
Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
EnsureConstructor(this);
i::FunctionTemplateInfo* constructor =
@@ -1225,12 +1220,12 @@
void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate,
"v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
EnsureConstructor(this);
i::FunctionTemplateInfo* constructor =
@@ -1241,7 +1236,7 @@
int ObjectTemplate::InternalFieldCount() {
- if (IsDeadCheck(i::Isolate::Current(),
+ if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
"v8::ObjectTemplate::InternalFieldCount()")) {
return 0;
}
@@ -1250,7 +1245,7 @@
void ObjectTemplate::SetInternalFieldCount(int value) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
return;
}
@@ -1259,7 +1254,7 @@
"Invalid internal field count")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
if (value > 0) {
// The internal field count is set by the constructor function's
// construct code, so we ensure that there is a constructor
@@ -1324,7 +1319,7 @@
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
LOG_API(isolate, "Script::New");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::String> str = Utils::OpenHandle(*source);
i::Handle<i::Object> name_obj;
int line_offset = 0;
@@ -1340,7 +1335,7 @@
column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
}
}
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
// We assert that the pre-data is sane, even though we can actually
// handle it if it turns out not to be in release mode.
@@ -1359,7 +1354,7 @@
Utils::OpenHandle(*script_data),
i::NOT_NATIVES_CODE);
has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(Local<Script>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
return Local<Script>(ToApi<Script>(result));
}
@@ -1378,7 +1373,7 @@
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
LOG_API(isolate, "Script::Compile");
- ENTER_V8;
+ ENTER_V8(isolate);
Local<Script> generic = New(source, origin, pre_data, script_data);
if (generic.IsEmpty())
return generic;
@@ -1388,7 +1383,7 @@
i::Handle<i::JSFunction> result =
isolate->factory()->NewFunctionFromSharedFunctionInfo(
function,
- i::Isolate::Current()->global_context());
+ isolate->global_context());
return Local<Script>(ToApi<Script>(result));
}
@@ -1405,29 +1400,29 @@
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
LOG_API(isolate, "Script::Run");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* raw_result = NULL;
{
- HandleScope scope;
+ i::HandleScope scope(isolate);
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSFunction> fun;
if (obj->IsSharedFunctionInfo()) {
i::Handle<i::SharedFunctionInfo>
- function_info(i::SharedFunctionInfo::cast(*obj));
+ function_info(i::SharedFunctionInfo::cast(*obj), isolate);
fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
- function_info, i::Isolate::Current()->global_context());
+ function_info, isolate->global_context());
} else {
- fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj));
+ fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
}
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> receiver(
- i::Isolate::Current()->context()->global_proxy());
+ isolate->context()->global_proxy(), isolate);
i::Handle<i::Object> result =
i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<Value>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
raw_result = *result;
}
- i::Handle<i::Object> result(raw_result);
+ i::Handle<i::Object> result(raw_result, isolate);
return Utils::ToLocal(result);
}
@@ -1493,13 +1488,14 @@
v8::TryCatch::~TryCatch() {
+ i::Isolate* isolate = i::Isolate::Current();
if (rethrow_) {
v8::HandleScope scope;
v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
- i::Isolate::Current()->UnregisterTryCatchHandler(this);
+ isolate->UnregisterTryCatchHandler(this);
v8::ThrowException(exc);
} else {
- i::Isolate::Current()->UnregisterTryCatchHandler(this);
+ isolate->UnregisterTryCatchHandler(this);
}
}
@@ -1578,9 +1574,9 @@
Local<String> Message::Get() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
@@ -1590,11 +1586,11 @@
v8::Handle<Value> Message::GetScriptResourceName() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
return Local<String>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1607,11 +1603,11 @@
v8::Handle<Value> Message::GetScriptData() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
return Local<Value>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1624,11 +1620,11 @@
v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
return Local<v8::StackTrace>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1670,24 +1666,24 @@
int Message::GetLineNumber() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
Utils::OpenHandle(this),
&has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(0);
+ EXCEPTION_BAILOUT_CHECK(isolate, 0);
return static_cast<int>(result->Number());
}
int Message::GetStartPosition() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1696,9 +1692,9 @@
int Message::GetEndPosition() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1707,35 +1703,35 @@
int Message::GetStartColumn() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
return kNoColumnInfo;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
"GetPositionInLine",
data_obj,
&has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(0);
+ EXCEPTION_BAILOUT_CHECK(isolate, 0);
return static_cast<int>(start_col_obj->Number());
}
int Message::GetEndColumn() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
"GetPositionInLine",
data_obj,
&has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(0);
+ EXCEPTION_BAILOUT_CHECK(isolate, 0);
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(data_obj);
int start = message->start_position();
@@ -1745,15 +1741,15 @@
Local<String> Message::GetSourceLine() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
Utils::OpenHandle(this),
&has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<v8::String>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
if (result->IsString()) {
return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
} else {
@@ -1765,7 +1761,7 @@
void Message::PrintCurrentStackTrace(FILE* out) {
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
isolate->PrintCurrentStackTrace(out);
}
@@ -1773,11 +1769,11 @@
// --- S t a c k T r a c e ---
Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
return Local<StackFrame>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSArray> self = Utils::OpenHandle(this);
i::Object* raw_object = self->GetElementNoExceptionThrown(index);
@@ -1787,17 +1783,17 @@
int StackTrace::GetFrameCount() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
- ENTER_V8;
+ ENTER_V8(isolate);
return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
}
Local<Array> StackTrace::AsArray() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
- ENTER_V8;
+ ENTER_V8(isolate);
return Utils::ToLocal(Utils::OpenHandle(this));
}
@@ -1808,7 +1804,7 @@
if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
Local<StackTrace>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSArray> stackTrace =
isolate->CaptureCurrentStackTrace(frame_limit, options);
return Utils::StackTraceToLocal(stackTrace);
@@ -1818,11 +1814,11 @@
// --- S t a c k F r a m e ---
int StackFrame::GetLineNumber() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
return Message::kNoLineNumberInfo;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> line = GetProperty(self, "lineNumber");
@@ -1834,11 +1830,11 @@
int StackFrame::GetColumn() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
return Message::kNoColumnInfo;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> column = GetProperty(self, "column");
@@ -1850,11 +1846,11 @@
Local<String> StackFrame::GetScriptName() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
return Local<String>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> name = GetProperty(self, "scriptName");
@@ -1866,11 +1862,11 @@
Local<String> StackFrame::GetScriptNameOrSourceURL() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
return Local<String>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
@@ -1882,11 +1878,11 @@
Local<String> StackFrame::GetFunctionName() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
return Local<String>();
}
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> name = GetProperty(self, "functionName");
@@ -1898,9 +1894,9 @@
bool StackFrame::IsEval() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
@@ -1909,9 +1905,9 @@
bool StackFrame::IsConstructor() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
@@ -2022,9 +2018,10 @@
bool Value::IsDate() const {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsDate()")) return false;
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
i::Handle<i::Object> obj = Utils::OpenHandle(this);
- return obj->HasSpecificClassOf(HEAP->Date_symbol());
+ return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
}
@@ -2036,74 +2033,76 @@
Local<String> Value::ToString() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(i::Isolate::Current(), "v8::Value::ToString()")) {
- return Local<String>();
- }
- LOG_API(isolate, "ToString");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> str;
if (obj->IsString()) {
str = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
+ return Local<String>();
+ }
+ LOG_API(isolate, "ToString");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
str = i::Execution::ToString(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<String>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
}
return Local<String>(ToApi<String>(str));
}
Local<String> Value::ToDetailString() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
- return Local<String>();
- }
- LOG_API(isolate, "ToDetailString");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> str;
if (obj->IsString()) {
str = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
+ return Local<String>();
+ }
+ LOG_API(isolate, "ToDetailString");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
str = i::Execution::ToDetailString(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<String>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
}
return Local<String>(ToApi<String>(str));
}
Local<v8::Object> Value::ToObject() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::ToObject()")) return Local<v8::Object>();
- LOG_API(isolate, "ToObject");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> val;
if (obj->IsJSObject()) {
val = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
+ return Local<v8::Object>();
+ }
+ LOG_API(isolate, "ToObject");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
val = i::Execution::ToObject(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
}
return Local<v8::Object>(ToApi<Object>(val));
}
Local<Boolean> Value::ToBoolean() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(i::Isolate::Current(), "v8::Value::ToBoolean()")) {
- return Local<Boolean>();
- }
- LOG_API(isolate, "ToBoolean");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsBoolean()) {
return Local<Boolean>(ToApi<Boolean>(obj));
} else {
- ENTER_V8;
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
+ return Local<Boolean>();
+ }
+ LOG_API(isolate, "ToBoolean");
+ ENTER_V8(isolate);
i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
return Local<Boolean>(ToApi<Boolean>(val));
}
@@ -2111,36 +2110,38 @@
Local<Number> Value::ToNumber() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) return Local<Number>();
- LOG_API(isolate, "ToNumber");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsNumber()) {
num = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
+ return Local<Number>();
+ }
+ LOG_API(isolate, "ToNumber");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
num = i::Execution::ToNumber(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<Number>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
}
return Local<Number>(ToApi<Number>(num));
}
Local<Integer> Value::ToInteger() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
- LOG_API(isolate, "ToInteger");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsSmi()) {
num = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
+ LOG_API(isolate, "ToInteger");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
num = i::Execution::ToInteger(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<Integer>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
}
return Local<Integer>(ToApi<Integer>(num));
}
@@ -2210,9 +2211,10 @@
void v8::Date::CheckCast(v8::Value* that) {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Date::Cast()")) return;
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- ApiCheck(obj->HasSpecificClassOf(HEAP->Date_symbol()),
+ ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
"v8::Date::Cast()",
"Could not convert to date");
}
@@ -2228,14 +2230,14 @@
bool Value::BooleanValue() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
- LOG_API(isolate, "BooleanValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsBoolean()) {
return obj->IsTrue();
} else {
- ENTER_V8;
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
+ LOG_API(isolate, "BooleanValue");
+ ENTER_V8(isolate);
i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
return value->IsTrue();
}
@@ -2243,38 +2245,38 @@
double Value::NumberValue() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
- return i::OS::nan_value();
- }
- LOG_API(isolate, "NumberValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsNumber()) {
num = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
+ return i::OS::nan_value();
+ }
+ LOG_API(isolate, "NumberValue");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
num = i::Execution::ToNumber(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(i::OS::nan_value());
+ EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
}
return num->Number();
}
int64_t Value::IntegerValue() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
- LOG_API(isolate, "IntegerValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsNumber()) {
num = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
+ LOG_API(isolate, "IntegerValue");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
num = i::Execution::ToInteger(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(0);
+ EXCEPTION_BAILOUT_CHECK(isolate, 0);
}
if (num->IsSmi()) {
return i::Smi::cast(*num)->value();
@@ -2285,55 +2287,55 @@
Local<Int32> Value::ToInt32() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
- LOG_API(isolate, "ToInt32");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsSmi()) {
num = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
+ LOG_API(isolate, "ToInt32");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
num = i::Execution::ToInt32(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<Int32>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
}
return Local<Int32>(ToApi<Int32>(num));
}
Local<Uint32> Value::ToUint32() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
- LOG_API(isolate, "ToUInt32");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsSmi()) {
num = obj;
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
+ LOG_API(isolate, "ToUInt32");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
num = i::Execution::ToUint32(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<Uint32>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
}
return Local<Uint32>(ToApi<Uint32>(num));
}
Local<Uint32> Value::ToArrayIndex() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
- LOG_API(isolate, "ToArrayIndex");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) {
if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
return Local<Uint32>();
}
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
+ LOG_API(isolate, "ToArrayIndex");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> string_obj =
i::Execution::ToString(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<Uint32>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
uint32_t index;
if (str->AsArrayIndex(&index)) {
@@ -2350,19 +2352,18 @@
int32_t Value::Int32Value() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
- LOG_API(isolate, "Int32Value");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) {
return i::Smi::cast(*obj)->value();
} else {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
LOG_API(isolate, "Int32Value (slow)");
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> num =
i::Execution::ToInt32(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(0);
+ EXCEPTION_BAILOUT_CHECK(isolate, 0);
if (num->IsSmi()) {
return i::Smi::cast(*num)->value();
} else {
@@ -2380,7 +2381,7 @@
return false;
}
LOG_API(isolate, "Equals");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> other = Utils::OpenHandle(*that);
// If both obj and other are JSObjects, we'd better compare by identity
@@ -2390,10 +2391,10 @@
return *obj == *other;
}
i::Object** args[1] = { other.location() };
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result =
CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(false);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
return *result == i::Smi::FromInt(i::EQUAL);
}
@@ -2431,18 +2432,18 @@
uint32_t Value::Uint32Value() const {
- i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
- LOG_API(isolate, "Uint32Value");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) {
return i::Smi::cast(*obj)->value();
} else {
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
+ LOG_API(isolate, "Uint32Value");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> num =
i::Execution::ToUint32(obj, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(0);
+ EXCEPTION_BAILOUT_CHECK(isolate, 0);
if (num->IsSmi()) {
return i::Smi::cast(*num)->value();
} else {
@@ -2454,14 +2455,14 @@
bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
v8::PropertyAttribute attribs) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::Set()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Object> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj = i::SetProperty(
self,
key_obj,
@@ -2469,26 +2470,26 @@
static_cast<PropertyAttributes>(attribs),
i::kNonStrictMode);
has_pending_exception = obj.is_null();
- EXCEPTION_BAILOUT_CHECK(false);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::Set()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj = i::SetElement(
self,
index,
value_obj,
i::kNonStrictMode);
has_pending_exception = obj.is_null();
- EXCEPTION_BAILOUT_CHECK(false);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
@@ -2496,29 +2497,29 @@
bool v8::Object::ForceSet(v8::Handle<Value> key,
v8::Handle<Value> value,
v8::PropertyAttribute attribs) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj = i::ForceSetProperty(
self,
key_obj,
value_obj,
static_cast<PropertyAttributes>(attribs));
has_pending_exception = obj.is_null();
- EXCEPTION_BAILOUT_CHECK(false);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
bool v8::Object::ForceDelete(v8::Handle<Value> key) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
@@ -2527,45 +2528,46 @@
// as optimized code does not always handle access checks.
i::Deoptimizer::DeoptimizeGlobalObject(*self);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
has_pending_exception = obj.is_null();
- EXCEPTION_BAILOUT_CHECK(false);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
return obj->IsTrue();
}
Local<Value> v8::Object::Get(v8::Handle<Value> key) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = i::GetProperty(self, key_obj);
has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(Local<Value>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
}
Local<Value> v8::Object::Get(uint32_t index) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = i::GetElement(self, index);
has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(Local<Value>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
}
Local<Value> v8::Object::GetPrototype() {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::GetPrototype()",
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
return Local<v8::Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> self = Utils::OpenHandle(this);
i::Handle<i::Object> result = i::GetPrototype(self);
return Utils::ToLocal(result);
@@ -2573,25 +2575,26 @@
bool v8::Object::SetPrototype(Handle<Value> value) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(false);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
Local<Object> v8::Object::FindInstanceInPrototypeChain(
v8::Handle<FunctionTemplate> tmpl) {
- ON_BAILOUT(i::Isolate::Current(),
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate,
"v8::Object::FindInstanceInPrototypeChain()",
return Local<v8::Object>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::JSObject* object = *Utils::OpenHandle(this);
i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
while (!object->IsInstanceOf(tmpl_info)) {
@@ -2604,11 +2607,11 @@
Local<Array> v8::Object::GetPropertyNames() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
return Local<v8::Array>());
- ENTER_V8;
- v8::HandleScope scope;
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::FixedArray> value =
i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
@@ -2618,14 +2621,15 @@
i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
i::Handle<i::JSArray> result =
isolate->factory()->NewJSArrayWithElements(elms);
- return scope.Close(Utils::ToLocal(result));
+ return Utils::ToLocal(scope.CloseAndEscape(result));
}
Local<String> v8::Object::ObjectProtoToString() {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::ObjectProtoToString()",
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
return Local<v8::String>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> name(self->class_name());
@@ -2676,10 +2680,10 @@
Local<String> v8::Object::GetConstructorName() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
return Local<v8::String>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> name(self->constructor_name());
return Utils::ToLocal(name);
@@ -2687,9 +2691,9 @@
bool v8::Object::Delete(v8::Handle<String> key) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
@@ -2698,8 +2702,9 @@
bool v8::Object::Has(v8::Handle<String> key) {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::Has()", return false);
- ENTER_V8;
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::Has()", return false);
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
return self->HasProperty(*key_obj);
@@ -2707,9 +2712,10 @@
bool v8::Object::Delete(uint32_t index) {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::DeleteProperty()",
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
return false);
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
return i::DeleteElement(self, index)->IsTrue();
@@ -2717,7 +2723,8 @@
bool v8::Object::Has(uint32_t index) {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasProperty()", return false);
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
return self->HasElement(index);
}
@@ -2729,9 +2736,9 @@
v8::Handle<Value> data,
AccessControl settings,
PropertyAttribute attributes) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
getter, setter, data,
@@ -2742,7 +2749,8 @@
bool v8::Object::HasRealNamedProperty(Handle<String> key) {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasRealNamedProperty()",
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
return false);
return Utils::OpenHandle(this)->HasRealNamedProperty(
*Utils::OpenHandle(*key));
@@ -2750,31 +2758,35 @@
bool v8::Object::HasRealIndexedProperty(uint32_t index) {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasRealIndexedProperty()",
+ ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
+ "v8::Object::HasRealIndexedProperty()",
return false);
return Utils::OpenHandle(this)->HasRealElementProperty(index);
}
bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
- ON_BAILOUT(i::Isolate::Current(),
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate,
"v8::Object::HasRealNamedCallbackProperty()",
return false);
- ENTER_V8;
+ ENTER_V8(isolate);
return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
*Utils::OpenHandle(*key));
}
bool v8::Object::HasNamedLookupInterceptor() {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasNamedLookupInterceptor()",
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
return false);
return Utils::OpenHandle(this)->HasNamedInterceptor();
}
bool v8::Object::HasIndexedLookupInterceptor() {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasIndexedLookupInterceptor()",
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
return false);
return Utils::OpenHandle(this)->HasIndexedInterceptor();
}
@@ -2782,10 +2794,11 @@
Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
Handle<String> key) {
- ON_BAILOUT(i::Isolate::Current(),
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate,
"v8::Object::GetRealNamedPropertyInPrototypeChain()",
return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::LookupResult lookup;
@@ -2805,9 +2818,10 @@
Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
- ON_BAILOUT(i::Isolate::Current(), "v8::Object::GetRealNamedProperty()",
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::LookupResult lookup;
@@ -2830,9 +2844,9 @@
// Because the object gets a new map, existing inline cache caching
// the old map of this object will fail.
void v8::Object::TurnOnAccessCheck() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
@@ -2841,7 +2855,7 @@
i::Deoptimizer::DeoptimizeGlobalObject(*obj);
i::Handle<i::Map> new_map =
- isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
+ isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
new_map->set_is_access_check_needed(true);
obj->set_map(*new_map);
}
@@ -2853,22 +2867,22 @@
Local<v8::Object> v8::Object::Clone() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::JSObject> result = i::Copy(self);
has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(Local<Object>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
return Utils::ToLocal(result);
}
int v8::Object::GetIdentityHash() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true));
@@ -2909,15 +2923,15 @@
bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
v8::Handle<v8::Value> value) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true));
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj = i::SetProperty(
hidden_props,
key_obj,
@@ -2925,26 +2939,26 @@
static_cast<PropertyAttributes>(None),
i::kNonStrictMode);
has_pending_exception = obj.is_null();
- EXCEPTION_BAILOUT_CHECK(false);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
return Local<v8::Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
if (hidden_props->IsUndefined()) {
return v8::Local<v8::Value>();
}
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(v8::Local<v8::Value>());
+ EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
if (result->IsUndefined()) {
return v8::Local<v8::Value>();
}
@@ -2953,9 +2967,9 @@
bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
@@ -2974,21 +2988,24 @@
void* data,
ExternalArrayType array_type,
int length) {
+ i::Isolate* isolate = object->GetIsolate();
i::Handle<i::ExternalArray> array =
- FACTORY->NewExternalArray(length, array_type, data);
+ isolate->factory()->NewExternalArray(length, array_type, data);
// If the object already has external elements, create a new, unique
// map if the element type is now changing, because assumptions about
// generated code based on the receiver's map will be invalid.
i::Handle<i::HeapObject> elements(object->elements());
- bool force_unique_map =
+ bool cant_reuse_map =
elements->map()->IsUndefined() ||
!elements->map()->has_external_array_elements() ||
- elements->map() != HEAP->MapForExternalArrayType(array_type);
- if (force_unique_map) {
+ elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
+ if (cant_reuse_map) {
i::Handle<i::Map> external_array_map =
- FACTORY->NewExternalArrayElementsMap(
- i::Handle<i::Map>(object->map()));
+ isolate->factory()->GetExternalArrayElementsMap(
+ i::Handle<i::Map>(object->map()),
+ array_type,
+ object->HasFastProperties());
object->set_map(*external_array_map);
}
object->set_elements(*array);
@@ -2998,9 +3015,9 @@
void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
"v8::Object::SetIndexedPropertiesToPixelData()",
@@ -3018,17 +3035,17 @@
bool v8::Object::HasIndexedPropertiesInPixelData() {
- ON_BAILOUT(i::Isolate::Current(), "v8::HasIndexedPropertiesInPixelData()",
- return false);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
+ return false);
return self->HasExternalPixelElements();
}
uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
- ON_BAILOUT(i::Isolate::Current(), "v8::GetIndexedPropertiesPixelData()",
- return NULL);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
+ return NULL);
if (self->HasExternalPixelElements()) {
return i::ExternalPixelArray::cast(self->elements())->
external_pixel_pointer();
@@ -3039,9 +3056,9 @@
int v8::Object::GetIndexedPropertiesPixelDataLength() {
- ON_BAILOUT(i::Isolate::Current(), "v8::GetIndexedPropertiesPixelDataLength()",
- return -1);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
+ return -1);
if (self->HasExternalPixelElements()) {
return i::ExternalPixelArray::cast(self->elements())->length();
} else {
@@ -3053,9 +3070,9 @@
void* data,
ExternalArrayType array_type,
int length) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
"v8::Object::SetIndexedPropertiesToExternalArrayData()",
@@ -3073,19 +3090,19 @@
bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
- ON_BAILOUT(i::Isolate::Current(),
+ i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ ON_BAILOUT(self->GetIsolate(),
"v8::HasIndexedPropertiesInExternalArrayData()",
return false);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
return self->HasExternalArrayElements();
}
void* v8::Object::GetIndexedPropertiesExternalArrayData() {
- ON_BAILOUT(i::Isolate::Current(),
+ i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ ON_BAILOUT(self->GetIsolate(),
"v8::GetIndexedPropertiesExternalArrayData()",
return NULL);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
if (self->HasExternalArrayElements()) {
return i::ExternalArray::cast(self->elements())->external_pointer();
} else {
@@ -3095,10 +3112,10 @@
ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
- ON_BAILOUT(i::Isolate::Current(),
+ i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ ON_BAILOUT(self->GetIsolate(),
"v8::GetIndexedPropertiesExternalArrayDataType()",
return static_cast<ExternalArrayType>(-1));
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
switch (self->elements()->map()->instance_type()) {
case i::EXTERNAL_BYTE_ARRAY_TYPE:
return kExternalByteArray;
@@ -3123,10 +3140,10 @@
int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
- ON_BAILOUT(i::Isolate::Current(),
+ i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ ON_BAILOUT(self->GetIsolate(),
"v8::GetIndexedPropertiesExternalArrayDataLength()",
return 0);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
if (self->HasExternalArrayElements()) {
return i::ExternalArray::cast(self->elements())->length();
} else {
@@ -3142,29 +3159,29 @@
Local<v8::Object> Function::NewInstance(int argc,
v8::Handle<v8::Value> argv[]) const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Function::NewInstance()",
return Local<v8::Object>());
LOG_API(isolate, "Function::NewInstance");
- ENTER_V8;
+ ENTER_V8(isolate);
HandleScope scope;
i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
i::Object*** args = reinterpret_cast<i::Object***>(argv);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned =
i::Execution::New(function, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
}
Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
v8::Handle<v8::Value> argv[]) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
LOG_API(isolate, "Function::Call");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* raw_result = NULL;
{
i::HandleScope scope(isolate);
@@ -3172,10 +3189,10 @@
i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
i::Object*** args = reinterpret_cast<i::Object***>(argv);
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned =
i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<Object>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
raw_result = *returned;
}
i::Handle<i::Object> result(raw_result);
@@ -3184,7 +3201,8 @@
void Function::SetName(v8::Handle<v8::String> name) {
- ENTER_V8;
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ENTER_V8(isolate);
i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
func->shared()->set_name(*Utils::OpenHandle(*name));
}
@@ -3224,14 +3242,16 @@
int String::Length() const {
- if (IsDeadCheck(i::Isolate::Current(), "v8::String::Length()")) return 0;
- return Utils::OpenHandle(this)->length();
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
+ return str->length();
}
int String::Utf8Length() const {
- if (IsDeadCheck(i::Isolate::Current(), "v8::String::Utf8Length()")) return 0;
- return Utils::OpenHandle(this)->Utf8Length();
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
+ return str->Utf8Length();
}
@@ -3239,10 +3259,10 @@
int capacity,
int* nchars_ref,
WriteHints hints) const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
LOG_API(isolate, "String::WriteUtf8");
- ENTER_V8;
+ ENTER_V8(isolate);
i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
i::Handle<i::String> str = Utils::OpenHandle(this);
isolate->string_tracker()->RecordWrite(str);
@@ -3296,10 +3316,10 @@
int start,
int length,
WriteHints hints) const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
LOG_API(isolate, "String::WriteAscii");
- ENTER_V8;
+ ENTER_V8(isolate);
i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this);
@@ -3330,10 +3350,10 @@
int start,
int length,
WriteHints hints) const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
LOG_API(isolate, "String::Write");
- ENTER_V8;
+ ENTER_V8(isolate);
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this);
isolate->string_tracker()->RecordWrite(str);
@@ -3355,15 +3375,20 @@
bool v8::String::IsExternal() const {
- EnsureInitialized("v8::String::IsExternal()");
i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
+ return false;
+ }
+ EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
return i::StringShape(*str).IsExternalTwoByte();
}
bool v8::String::IsExternalAscii() const {
- EnsureInitialized("v8::String::IsExternalAscii()");
i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
+ return false;
+ }
return i::StringShape(*str).IsExternalAscii();
}
@@ -3384,8 +3409,11 @@
v8::String::ExternalAsciiStringResource*
v8::String::GetExternalAsciiStringResource() const {
- EnsureInitialized("v8::String::GetExternalAsciiStringResource()");
i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(),
+ "v8::String::GetExternalAsciiStringResource()")) {
+ return NULL;
+ }
if (i::StringShape(*str).IsExternalAscii()) {
void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
return reinterpret_cast<ExternalAsciiStringResource*>(resource);
@@ -3443,19 +3471,19 @@
int v8::Object::InternalFieldCount() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Object::InternalFieldCount()")) {
+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
return 0;
}
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
return obj->GetInternalFieldCount();
}
Local<Value> v8::Object::CheckedGetInternalField(int index) {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Object::GetInternalField()")) {
+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
return Local<Value>();
}
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
if (!ApiCheck(index < obj->GetInternalFieldCount(),
"v8::Object::GetInternalField()",
"Reading internal field out of bounds")) {
@@ -3472,16 +3500,17 @@
void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Object::SetInternalField()")) {
+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ i::Isolate* isolate = obj->GetIsolate();
+ if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
return;
}
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
if (!ApiCheck(index < obj->GetInternalFieldCount(),
"v8::Object::SetInternalField()",
"Writing internal field out of bounds")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> val = Utils::OpenHandle(*value);
obj->SetInternalField(index, *val);
}
@@ -3505,13 +3534,15 @@
void v8::Object::SetPointerInInternalField(int index, void* value) {
- ENTER_V8;
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ENTER_V8(isolate);
if (CanBeEncodedAsSmi(value)) {
Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
} else {
HandleScope scope;
i::Handle<i::Proxy> proxy =
- FACTORY->NewProxy(reinterpret_cast<i::Address>(value), i::TENURED);
+ isolate->factory()->NewProxy(
+ reinterpret_cast<i::Address>(value), i::TENURED);
if (!proxy.is_null())
Utils::OpenHandle(this)->SetInternalField(index, *proxy);
}
@@ -3550,11 +3581,12 @@
void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
- heap_statistics->set_total_heap_size(HEAP->CommittedMemory());
+ i::Heap* heap = i::Isolate::Current()->heap();
+ heap_statistics->set_total_heap_size(heap->CommittedMemory());
heap_statistics->set_total_heap_size_executable(
- HEAP->CommittedMemoryExecutable());
- heap_statistics->set_used_heap_size(HEAP->SizeOfObjects());
- heap_statistics->set_heap_size_limit(HEAP->MaxReserved());
+ heap->CommittedMemoryExecutable());
+ heap_statistics->set_used_heap_size(heap->SizeOfObjects());
+ heap_statistics->set_heap_size_limit(heap->MaxReserved());
}
@@ -3567,14 +3599,16 @@
void v8::V8::LowMemoryNotification() {
- if (!i::Isolate::Current()->IsInitialized()) return;
- HEAP->CollectAllGarbage(true);
+ i::Isolate* isolate = i::Isolate::Current();
+ if (!isolate->IsInitialized()) return;
+ isolate->heap()->CollectAllGarbage(true);
}
int v8::V8::ContextDisposedNotification() {
- if (!i::Isolate::Current()->IsInitialized()) return 0;
- return HEAP->NotifyContextDisposed();
+ i::Isolate* isolate = i::Isolate::Current();
+ if (!isolate->IsInitialized()) return 0;
+ return isolate->heap()->NotifyContextDisposed();
}
@@ -3607,7 +3641,7 @@
// Enter V8 via an ENTER_V8 scope.
i::Handle<i::Context> env;
{
- ENTER_V8;
+ ENTER_V8(isolate);
v8::Handle<ObjectTemplate> proxy_template = global_template;
i::Handle<i::FunctionTemplateInfo> proxy_constructor;
i::Handle<i::FunctionTemplateInfo> global_constructor;
@@ -3636,7 +3670,8 @@
proxy_constructor->set_needs_access_check(
global_constructor->needs_access_check());
global_constructor->set_needs_access_check(false);
- global_constructor->set_access_check_info(HEAP->undefined_value());
+ global_constructor->set_access_check_info(
+ isolate->heap()->undefined_value());
}
}
@@ -3655,7 +3690,7 @@
global_constructor->set_needs_access_check(
proxy_constructor->needs_access_check());
}
- i::Isolate::Current()->runtime_profiler()->Reset();
+ isolate->runtime_profiler()->Reset();
}
// Leave V8.
@@ -3666,10 +3701,11 @@
void v8::Context::SetSecurityToken(Handle<Value> token) {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::SetSecurityToken()")) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Context> env = Utils::OpenHandle(this);
i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
env->set_security_token(*token_handle);
@@ -3677,18 +3713,20 @@
void v8::Context::UseDefaultSecurityToken() {
- if (IsDeadCheck(i::Isolate::Current(),
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate,
"v8::Context::UseDefaultSecurityToken()")) {
return;
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Context> env = Utils::OpenHandle(this);
env->set_security_token(env->global());
}
Handle<Value> v8::Context::GetSecurityToken() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetSecurityToken()")) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
return Handle<Value>();
}
i::Handle<i::Context> env = Utils::OpenHandle(this);
@@ -3710,11 +3748,12 @@
v8::Local<v8::Context> Context::GetEntered() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetEntered()")) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
return Local<Context>();
}
i::Handle<i::Object> last =
- i::Isolate::Current()->handle_scope_implementer()->LastEnteredContext();
+ isolate->handle_scope_implementer()->LastEnteredContext();
if (last.is_null()) return Local<Context>();
i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
return Utils::ToLocal(context);
@@ -3722,10 +3761,11 @@
v8::Local<v8::Context> Context::GetCurrent() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetCurrent()")) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
return Local<Context>();
}
- i::Handle<i::Object> current = i::Isolate::Current()->global_context();
+ i::Handle<i::Object> current = isolate->global_context();
if (current.is_null()) return Local<Context>();
i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
return Utils::ToLocal(context);
@@ -3733,11 +3773,12 @@
v8::Local<v8::Context> Context::GetCalling() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetCalling()")) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
return Local<Context>();
}
i::Handle<i::Object> calling =
- i::Isolate::Current()->GetCallingGlobalContext();
+ isolate->GetCallingGlobalContext();
if (calling.is_null()) return Local<Context>();
i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
return Utils::ToLocal(context);
@@ -3757,19 +3798,20 @@
void Context::DetachGlobal() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::DetachGlobal()")) return;
- ENTER_V8;
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
+ ENTER_V8(isolate);
i::Object** ctx = reinterpret_cast<i::Object**>(this);
i::Handle<i::Context> context =
i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
- i::Isolate::Current()->bootstrapper()->DetachGlobal(context);
+ isolate->bootstrapper()->DetachGlobal(context);
}
void Context::ReattachGlobal(Handle<Object> global_object) {
i::Isolate* isolate = i::Isolate::Current();
if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object** ctx = reinterpret_cast<i::Object**>(this);
i::Handle<i::Context> context =
i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
@@ -3789,12 +3831,12 @@
ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
return Local<v8::Object>());
LOG_API(isolate, "ObjectTemplate::NewInstance");
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj =
i::Execution::InstantiateObject(Utils::OpenHandle(this),
&has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
}
@@ -3804,12 +3846,12 @@
ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
return Local<v8::Function>());
LOG_API(isolate, "FunctionTemplate::GetFunction");
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj =
i::Execution::InstantiateFunction(Utils::OpenHandle(this),
&has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<v8::Function>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
}
@@ -3836,7 +3878,7 @@
STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
LOG_API(isolate, "External::Wrap");
EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
- ENTER_V8;
+ ENTER_V8(isolate);
v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
@@ -3881,7 +3923,7 @@
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "External::New");
EnsureInitializedForIsolate(isolate, "v8::External::New()");
- ENTER_V8;
+ ENTER_V8(isolate);
return ExternalNewImpl(data);
}
@@ -3906,7 +3948,7 @@
EnsureInitializedForIsolate(isolate, "v8::String::New()");
LOG_API(isolate, "String::New(char)");
if (length == 0) return Empty();
- ENTER_V8;
+ ENTER_V8(isolate);
if (length == -1) length = i::StrLength(data);
i::Handle<i::String> result =
isolate->factory()->NewStringFromUtf8(
@@ -3918,9 +3960,9 @@
Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
i::Handle<i::String> left_string = Utils::OpenHandle(*left);
i::Isolate* isolate = left_string->GetIsolate();
- EnsureInitializedForIsolate(isolate, "v8::String::Concat()");
- LOG_API(isolate, "String::Concat()");
- ENTER_V8;
+ EnsureInitializedForIsolate(isolate, "v8::String::New()");
+ LOG_API(isolate, "String::New(char)");
+ ENTER_V8(isolate);
i::Handle<i::String> right_string = Utils::OpenHandle(*right);
i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
right_string);
@@ -3932,7 +3974,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
LOG_API(isolate, "String::NewUndetectable(char)");
- ENTER_V8;
+ ENTER_V8(isolate);
if (length == -1) length = i::StrLength(data);
i::Handle<i::String> result =
isolate->factory()->NewStringFromUtf8(
@@ -3954,7 +3996,7 @@
EnsureInitializedForIsolate(isolate, "v8::String::New()");
LOG_API(isolate, "String::New(uint16_)");
if (length == 0) return Empty();
- ENTER_V8;
+ ENTER_V8(isolate);
if (length == -1) length = TwoByteStringLength(data);
i::Handle<i::String> result =
isolate->factory()->NewStringFromTwoByte(
@@ -3967,7 +4009,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
LOG_API(isolate, "String::NewUndetectable(uint16_)");
- ENTER_V8;
+ ENTER_V8(isolate);
if (length == -1) length = TwoByteStringLength(data);
i::Handle<i::String> result =
isolate->factory()->NewStringFromTwoByte(
@@ -3998,7 +4040,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
LOG_API(isolate, "String::NewExternal");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
isolate->heap()->external_string_table()->AddString(*result);
return Utils::ToLocal(result);
@@ -4009,8 +4051,10 @@
i::Handle<i::String> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
- if (this->IsExternal()) return false; // Already an external string.
- ENTER_V8;
+ if (i::StringShape(*obj).IsExternalTwoByte()) {
+ return false; // Already an external string.
+ }
+ ENTER_V8(isolate);
if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
return false;
}
@@ -4027,7 +4071,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
LOG_API(isolate, "String::NewExternal");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
isolate->heap()->external_string_table()->AddString(*result);
return Utils::ToLocal(result);
@@ -4039,8 +4083,10 @@
i::Handle<i::String> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
- if (this->IsExternal()) return false; // Already an external string.
- ENTER_V8;
+ if (i::StringShape(*obj).IsExternalTwoByte()) {
+ return false; // Already an external string.
+ }
+ ENTER_V8(isolate);
if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
return false;
}
@@ -4071,9 +4117,9 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Object::New()");
LOG_API(isolate, "Object::New");
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::JSObject> obj =
- isolate->factory()->NewJSObject(i::Isolate::Current()->object_function());
+ isolate->factory()->NewJSObject(isolate->object_function());
return Utils::ToLocal(obj);
}
@@ -4086,11 +4132,11 @@
// Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
time = i::OS::nan_value();
}
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj =
i::Execution::NewDate(time, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<v8::Value>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
return Utils::ToLocal(obj);
}
@@ -4110,7 +4156,7 @@
ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
return);
LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
// Get the function ResetDateCache (defined in date-delay.js).
@@ -4150,22 +4196,22 @@
Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
Flags flags) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
LOG_API(isolate, "RegExp::New");
- ENTER_V8;
- EXCEPTION_PREAMBLE();
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
Utils::OpenHandle(*pattern),
RegExpFlagsToString(flags),
&has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(Local<v8::RegExp>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
}
Local<v8::String> v8::RegExp::GetSource() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
return Local<v8::String>();
}
@@ -4197,7 +4243,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Array::New()");
LOG_API(isolate, "Array::New");
- ENTER_V8;
+ ENTER_V8(isolate);
int real_length = length > 0 ? length : 0;
i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
obj->set_length(*isolate->factory()->NewNumberFromInt(real_length));
@@ -4206,7 +4252,7 @@
uint32_t v8::Array::Length() const {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
i::Object* length = obj->length();
@@ -4219,7 +4265,7 @@
Local<Object> Array::CloneElementAt(uint32_t index) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
if (!self->HasFastElements()) {
@@ -4231,11 +4277,11 @@
return Local<Object>();
}
i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
- EXCEPTION_PREAMBLE();
- ENTER_V8;
+ EXCEPTION_PREAMBLE(isolate);
+ ENTER_V8(isolate);
i::Handle<i::JSObject> result = i::Copy(paragon_handle);
has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(Local<Object>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
return Utils::ToLocal(result);
}
@@ -4244,7 +4290,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
LOG_API(isolate, "String::NewSymbol(char)");
- ENTER_V8;
+ ENTER_V8(isolate);
if (length == -1) length = i::StrLength(data);
i::Handle<i::String> result =
isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
@@ -4259,7 +4305,7 @@
// Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
value = i::OS::nan_value();
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
return Utils::NumberToLocal(result);
}
@@ -4272,7 +4318,7 @@
return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
isolate));
}
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
return Utils::IntegerToLocal(result);
}
@@ -4283,8 +4329,9 @@
if (fits_into_int32_t) {
return Integer::New(static_cast<int32_t>(value));
}
- ENTER_V8;
- i::Handle<i::Object> result = FACTORY->NewNumber(value);
+ i::Isolate* isolate = i::Isolate::Current();
+ ENTER_V8(isolate);
+ i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
return Utils::IntegerToLocal(result);
}
@@ -4299,13 +4346,13 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
NeanderArray listeners(isolate->factory()->message_listeners());
NeanderObject obj(2);
obj.set(0, *isolate->factory()->NewProxy(FUNCTION_ADDR(that)));
obj.set(1, data.IsEmpty() ?
- HEAP->undefined_value() :
+ isolate->heap()->undefined_value() :
*Utils::OpenHandle(*data));
listeners.add(obj.value());
return true;
@@ -4316,7 +4363,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
NeanderArray listeners(isolate->factory()->message_listeners());
for (int i = 0; i < listeners.length(); i++) {
@@ -4325,7 +4372,7 @@
NeanderObject listener(i::JSObject::cast(listeners.get(i)));
i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
- listeners.set(i, HEAP->undefined_value());
+ listeners.set(i, isolate->heap()->undefined_value());
}
}
}
@@ -4495,21 +4542,22 @@
void V8::ResumeProfilerEx(int flags, int tag) {
#ifdef ENABLE_LOGGING_AND_PROFILING
+ i::Isolate* isolate = i::Isolate::Current();
if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
// Snapshot mode: resume modules, perform GC, then pause only
// those modules which haven't been started prior to making a
// snapshot.
// Make a GC prior to taking a snapshot.
- HEAP->CollectAllGarbage(false);
+ isolate->heap()->CollectAllGarbage(false);
// Reset snapshot flag and CPU module flags.
flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
- const int current_flags = LOGGER->GetActiveProfilerModules();
- LOGGER->ResumeProfiler(flags, tag);
- HEAP->CollectAllGarbage(false);
- LOGGER->PauseProfiler(~current_flags & flags, tag);
+ const int current_flags = isolate->logger()->GetActiveProfilerModules();
+ isolate->logger()->ResumeProfiler(flags, tag);
+ isolate->heap()->CollectAllGarbage(false);
+ isolate->logger()->PauseProfiler(~current_flags & flags, tag);
} else {
- LOGGER->ResumeProfiler(flags, tag);
+ isolate->logger()->ResumeProfiler(flags, tag);
}
#endif
}
@@ -4541,16 +4589,16 @@
int V8::GetCurrentThreadId() {
- API_ENTRY_CHECK("V8::GetCurrentThreadId()");
- EnsureInitialized("V8::GetCurrentThreadId()");
- return i::Isolate::Current()->thread_id();
+ i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
+ return isolate->thread_id();
}
void V8::TerminateExecution(int thread_id) {
- if (!i::Isolate::Current()->IsInitialized()) return;
- API_ENTRY_CHECK("V8::GetCurrentThreadId()");
i::Isolate* isolate = i::Isolate::Current();
+ if (!isolate->IsInitialized()) return;
+ API_ENTRY_CHECK("V8::TerminateExecution()");
// If the thread_id identifies the current thread just terminate
// execution right away. Otherwise, ask the thread manager to
// terminate the thread with the given id if any.
@@ -4573,12 +4621,8 @@
bool V8::IsExecutionTerminating() {
- if (!i::Isolate::Current()->IsInitialized()) return false;
- if (i::Isolate::Current()->has_scheduled_exception()) {
- return i::Isolate::Current()->scheduled_exception() ==
- HEAP->termination_exception();
- }
- return false;
+ i::Isolate* isolate = i::Isolate::Current();
+ return IsExecutionTerminatingCheck(isolate);
}
@@ -4618,14 +4662,15 @@
String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
- EnsureInitialized("v8::String::Utf8Value::Utf8Value()");
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
if (obj.IsEmpty()) {
str_ = NULL;
length_ = 0;
return;
}
- ENTER_V8;
- HandleScope scope;
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
TryCatch try_catch;
Handle<String> str = obj->ToString();
if (str.IsEmpty()) {
@@ -4645,14 +4690,15 @@
String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
- EnsureInitialized("v8::String::AsciiValue::AsciiValue()");
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
if (obj.IsEmpty()) {
str_ = NULL;
length_ = 0;
return;
}
- ENTER_V8;
- HandleScope scope;
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
TryCatch try_catch;
Handle<String> str = obj->ToString();
if (str.IsEmpty()) {
@@ -4672,14 +4718,15 @@
String::Value::Value(v8::Handle<v8::Value> obj) {
- EnsureInitialized("v8::String::Value::Value()");
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
if (obj.IsEmpty()) {
str_ = NULL;
length_ = 0;
return;
}
- ENTER_V8;
- HandleScope scope;
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
TryCatch try_catch;
Handle<String> str = obj->ToString();
if (str.IsEmpty()) {
@@ -4701,7 +4748,7 @@
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "RangeError");
ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* error;
{
i::HandleScope scope(isolate);
@@ -4717,7 +4764,7 @@
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "ReferenceError");
ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* error;
{
i::HandleScope scope(isolate);
@@ -4734,7 +4781,7 @@
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "SyntaxError");
ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* error;
{
i::HandleScope scope(isolate);
@@ -4750,7 +4797,7 @@
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "TypeError");
ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* error;
{
i::HandleScope scope(isolate);
@@ -4766,7 +4813,7 @@
i::Isolate* isolate = i::Isolate::Current();
LOG_API(isolate, "Error");
ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Object* error;
{
i::HandleScope scope(isolate);
@@ -4798,7 +4845,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
isolate->set_debug_event_callback(that);
@@ -4816,7 +4863,7 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
if (that != NULL) {
@@ -4832,7 +4879,7 @@
Handle<Value> data) {
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
- ENTER_V8;
+ ENTER_V8(isolate);
isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
Utils::OpenHandle(*data));
return true;
@@ -4882,27 +4929,29 @@
void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
bool message_handler_thread) {
- EnsureInitialized("v8::Debug::SetMessageHandler");
- ENTER_V8;
i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
+ ENTER_V8(isolate);
+
// Message handler thread not supported any more. Parameter temporally left in
- // the API for client compatability reasons.
+ // the API for client compatibility reasons.
CHECK(!message_handler_thread);
// TODO(sgjesse) support the old message handler API through a simple wrapper.
isolate->set_message_handler(handler);
if (handler != NULL) {
- i::Isolate::Current()->debugger()->SetMessageHandler(MessageHandlerWrapper);
+ isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
} else {
- i::Isolate::Current()->debugger()->SetMessageHandler(NULL);
+ isolate->debugger()->SetMessageHandler(NULL);
}
}
void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
- EnsureInitialized("v8::Debug::SetMessageHandler");
- ENTER_V8;
- i::Isolate::Current()->debugger()->SetMessageHandler(handler);
+ i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
+ ENTER_V8(isolate);
+ isolate->debugger()->SetMessageHandler(handler);
}
@@ -4923,17 +4972,20 @@
void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
int period) {
- EnsureInitialized("v8::Debug::SetHostDispatchHandler");
- ENTER_V8;
- i::Isolate::Current()->debugger()->SetHostDispatchHandler(handler, period);
+ i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
+ ENTER_V8(isolate);
+ isolate->debugger()->SetHostDispatchHandler(handler, period);
}
void Debug::SetDebugMessageDispatchHandler(
DebugMessageDispatchHandler handler, bool provide_locker) {
- EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler");
- ENTER_V8;
- i::Isolate::Current()->debugger()->SetDebugMessageDispatchHandler(
+ i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate,
+ "v8::Debug::SetDebugMessageDispatchHandler");
+ ENTER_V8(isolate);
+ isolate->debugger()->SetDebugMessageDispatchHandler(
handler, provide_locker);
}
@@ -4943,20 +4995,19 @@
i::Isolate* isolate = i::Isolate::Current();
if (!isolate->IsInitialized()) return Local<Value>();
ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
i::Handle<i::Object> result;
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
if (data.IsEmpty()) {
- result = i::Isolate::Current()->debugger()->Call(
- Utils::OpenHandle(*fun),
- isolate->factory()->undefined_value(),
- &has_pending_exception);
+ result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
+ isolate->factory()->undefined_value(),
+ &has_pending_exception);
} else {
- result = i::Isolate::Current()->debugger()->Call(Utils::OpenHandle(*fun),
- Utils::OpenHandle(*data),
- &has_pending_exception);
+ result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
+ Utils::OpenHandle(*data),
+ &has_pending_exception);
}
- EXCEPTION_BAILOUT_CHECK(Local<Value>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
}
@@ -4965,9 +5016,9 @@
i::Isolate* isolate = i::Isolate::Current();
if (!isolate->IsInitialized()) return Local<Value>();
ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
- ENTER_V8;
+ ENTER_V8(isolate);
v8::HandleScope scope;
- i::Debug* isolate_debug = i::Isolate::Current()->debug();
+ i::Debug* isolate_debug = isolate->debug();
isolate_debug->Load();
i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
i::Handle<i::String> name =
@@ -4977,11 +5028,11 @@
v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
const int kArgc = 1;
v8::Handle<v8::Value> argv[kArgc] = { obj };
- EXCEPTION_PREAMBLE();
+ EXCEPTION_PREAMBLE(isolate);
v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
kArgc,
argv);
- EXCEPTION_BAILOUT_CHECK(Local<Value>());
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return scope.Close(result);
}
@@ -4996,8 +5047,9 @@
}
Local<Context> Debug::GetDebugContext() {
- EnsureInitialized("v8::Debug::GetDebugContext()");
- ENTER_V8;
+ i::Isolate* isolate = i::Isolate::Current();
+ EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
+ ENTER_V8(isolate);
return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
}
@@ -5216,7 +5268,7 @@
edge->index())));
default: UNREACHABLE();
}
- return ImplementationUtilities::Undefined();
+ return v8::Undefined();
}
diff --git a/src/apiutils.h b/src/apiutils.h
index 149ede5..68579af 100644
--- a/src/apiutils.h
+++ b/src/apiutils.h
@@ -31,11 +31,6 @@
namespace v8 {
class ImplementationUtilities {
public:
- static v8::Handle<v8::Primitive> Undefined();
- static v8::Handle<v8::Primitive> Null();
- static v8::Handle<v8::Boolean> True();
- static v8::Handle<v8::Boolean> False();
-
static int GetNameCount(ExtensionConfiguration* that) {
return that->name_count_;
}
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index e6d6525..f401cfd 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -310,6 +310,7 @@
// construct call and normal call.
static void ArrayNativeCode(MacroAssembler* masm,
Label* call_generic_code) {
+ Counters* counters = masm->isolate()->counters();
Label argc_one_or_more, argc_two_or_more;
// Check for array construction with zero arguments or one.
@@ -325,7 +326,7 @@
r5,
JSArray::kPreallocatedArrayElements,
call_generic_code);
- __ IncrementCounter(COUNTERS->array_function_native(), 1, r3, r4);
+ __ IncrementCounter(counters->array_function_native(), 1, r3, r4);
// Setup return value, remove receiver from stack and return.
__ mov(r0, r2);
__ add(sp, sp, Operand(kPointerSize));
@@ -361,7 +362,7 @@
r7,
true,
call_generic_code);
- __ IncrementCounter(COUNTERS->array_function_native(), 1, r2, r4);
+ __ IncrementCounter(counters->array_function_native(), 1, r2, r4);
// Setup return value, remove receiver and argument from stack and return.
__ mov(r0, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
@@ -385,7 +386,7 @@
r7,
false,
call_generic_code);
- __ IncrementCounter(COUNTERS->array_function_native(), 1, r2, r6);
+ __ IncrementCounter(counters->array_function_native(), 1, r2, r6);
// Fill arguments as array elements. Copy from the top of the stack (last
// element) to the array backing store filling it backwards. Note:
@@ -442,9 +443,9 @@
// Jump to the generic array code if the specialized code cannot handle
// the construction.
__ bind(&generic_array_code);
- Code* code = masm->isolate()->builtins()->builtin(
- Builtins::ArrayCodeGeneric);
- Handle<Code> array_code(code);
+
+ Handle<Code> array_code =
+ masm->isolate()->builtins()->ArrayCodeGeneric();
__ Jump(array_code, RelocInfo::CODE_TARGET);
}
@@ -475,9 +476,8 @@
// Jump to the generic construct code in case the specialized code cannot
// handle the construction.
__ bind(&generic_constructor);
- Code* code = masm->isolate()->builtins()->builtin(
- Builtins::JSConstructStubGeneric);
- Handle<Code> generic_construct_stub(code);
+ Handle<Code> generic_construct_stub =
+ masm->isolate()->builtins()->JSConstructStubGeneric();
__ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
}
@@ -490,7 +490,8 @@
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
// -----------------------------------
- __ IncrementCounter(COUNTERS->string_ctor_calls(), 1, r2, r3);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->string_ctor_calls(), 1, r2, r3);
Register function = r1;
if (FLAG_debug_code) {
@@ -520,7 +521,7 @@
r5, // Scratch.
false, // Is it a Smi?
¬_cached);
- __ IncrementCounter(COUNTERS->string_ctor_cached_number(), 1, r3, r4);
+ __ IncrementCounter(counters->string_ctor_cached_number(), 1, r3, r4);
__ bind(&argument_is_string);
// ----------- S t a t e -------------
@@ -574,13 +575,13 @@
__ tst(r3, Operand(kIsNotStringMask));
__ b(ne, &convert_argument);
__ mov(argument, r0);
- __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1, r3, r4);
+ __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
__ b(&argument_is_string);
// Invoke the conversion builtin and put the result into r2.
__ bind(&convert_argument);
__ push(function); // Preserve the function.
- __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1, r3, r4);
+ __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
__ EnterInternalFrame();
__ push(r0);
__ InvokeBuiltin(Builtins::TO_STRING, CALL_JS);
@@ -599,7 +600,7 @@
// At this point the argument is already a string. Call runtime to
// create a string wrapper.
__ bind(&gc_required);
- __ IncrementCounter(COUNTERS->string_ctor_gc_required(), 1, r3, r4);
+ __ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4);
__ EnterInternalFrame();
__ push(argument);
__ CallRuntime(Runtime::kNewStringWrapper, 1);
@@ -635,8 +636,8 @@
// Set expected number of arguments to zero (not changing r0).
__ mov(r2, Operand(0, RelocInfo::NONE));
__ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
- __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
}
@@ -646,6 +647,8 @@
// Should never count constructions for api objects.
ASSERT(!is_api_function || !count_constructions);
+ Isolate* isolate = masm->isolate();
+
// Enter a construct frame.
__ EnterConstructFrame();
@@ -661,7 +664,7 @@
Label undo_allocation;
#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference debug_step_in_fp =
- ExternalReference::debug_step_in_fp_address(masm->isolate());
+ ExternalReference::debug_step_in_fp_address(isolate);
__ mov(r2, Operand(debug_step_in_fp));
__ ldr(r2, MemOperand(r2));
__ tst(r2, r2);
@@ -907,9 +910,8 @@
// r1: constructor function
if (is_api_function) {
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
- Handle<Code> code = Handle<Code>(
- masm->isolate()->builtins()->builtin(
- Builtins::HandleApiCallConstruct));
+ Handle<Code> code =
+ masm->isolate()->builtins()->HandleApiCallConstruct();
ParameterCount expected(0);
__ InvokeCode(code, expected, expected,
RelocInfo::CODE_TARGET, CALL_FUNCTION);
@@ -966,7 +968,7 @@
__ LeaveConstructFrame();
__ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
__ add(sp, sp, Operand(kPointerSize));
- __ IncrementCounter(COUNTERS->constructed_objects(), 1, r1, r2);
+ __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2);
__ Jump(lr);
}
@@ -1043,8 +1045,8 @@
// Invoke the code and pass argc as r0.
__ mov(r0, Operand(r3));
if (is_construct) {
- __ Call(Handle<Code>(masm->isolate()->builtins()->builtin(
- Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
+ __ Call(masm->isolate()->builtins()->JSConstructCall(),
+ RelocInfo::CODE_TARGET);
} else {
ParameterCount actual(r0);
__ InvokeFunction(r1, actual, CALL_FUNCTION);
@@ -1336,8 +1338,8 @@
// Expected number of arguments is 0 for CALL_NON_FUNCTION.
__ mov(r2, Operand(0, RelocInfo::NONE));
__ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
- __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
__ bind(&function);
}
@@ -1352,8 +1354,9 @@
__ mov(r2, Operand(r2, ASR, kSmiTagSize));
__ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
__ cmp(r2, r0); // Check formal and actual parameter counts.
- __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET, ne);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET,
+ ne);
ParameterCount expected(0);
__ InvokeCode(r3, expected, expected, JUMP_FUNCTION);
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index e7b563c..c25d445 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -1458,11 +1458,12 @@
// number string cache for smis is just the smi value, and the hash for
// doubles is the xor of the upper and lower words. See
// Heap::GetNumberStringCache.
+ Isolate* isolate = masm->isolate();
Label is_smi;
Label load_result_from_cache;
if (!object_is_smi) {
__ JumpIfSmi(object, &is_smi);
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ if (isolate->cpu_features()->IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
__ CheckMap(object,
scratch1,
@@ -1519,7 +1520,7 @@
__ bind(&load_result_from_cache);
__ ldr(result,
FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize));
- __ IncrementCounter(COUNTERS->number_to_string_native(),
+ __ IncrementCounter(isolate->counters()->number_to_string_native(),
1,
scratch1,
scratch2);
@@ -1595,7 +1596,8 @@
__ bind(&both_loaded_as_doubles);
// The arguments have been converted to doubles and stored in d6 and d7, if
// VFP3 is supported, or in r0, r1, r2, and r3.
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ Isolate* isolate = masm->isolate();
+ if (isolate->cpu_features()->IsSupported(VFP3)) {
__ bind(&lhs_not_nan);
CpuFeatures::Scope scope(VFP3);
Label no_nan;
@@ -1665,7 +1667,7 @@
__ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow);
- __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3);
+ __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3);
StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
lhs_,
rhs_,
@@ -4494,11 +4496,11 @@
// r3: argc
// r4: argv
if (is_construct) {
- ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline,
+ ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
isolate);
__ mov(ip, Operand(construct_entry));
} else {
- ExternalReference entry(Builtins::JSEntryTrampoline, isolate);
+ ExternalReference entry(Builtins::kJSEntryTrampoline, isolate);
__ mov(ip, Operand(entry));
}
__ ldr(ip, MemOperand(ip)); // deref address
@@ -5089,7 +5091,7 @@
// subject: Subject string
// regexp_data: RegExp data (FixedArray)
// All checks done. Now push arguments for native regexp code.
- __ IncrementCounter(COUNTERS->regexp_entry_native(), 1, r0, r2);
+ __ IncrementCounter(isolate->counters()->regexp_entry_native(), 1, r0, r2);
// Isolates: note we add an additional parameter here (isolate pointer).
static const int kRegExpExecuteArguments = 8;
@@ -5397,8 +5399,7 @@
__ mov(r0, Operand(argc_)); // Setup the number of arguments.
__ mov(r2, Operand(0, RelocInfo::NONE));
__ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
- __ Jump(Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::ArgumentsAdaptorTrampoline)),
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
}
@@ -6105,7 +6106,6 @@
static const int kFromOffset = 1 * kPointerSize;
static const int kStringOffset = 2 * kPointerSize;
-
// Check bounds and smi-ness.
Register to = r6;
Register from = r7;
@@ -6206,7 +6206,8 @@
Label make_two_character_string;
StringHelper::GenerateTwoCharacterSymbolTableProbe(
masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string);
- __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
__ add(sp, sp, Operand(3 * kPointerSize));
__ Ret();
@@ -6215,7 +6216,7 @@
__ bind(&make_two_character_string);
__ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime);
__ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
- __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+ __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
__ add(sp, sp, Operand(3 * kPointerSize));
__ Ret();
@@ -6241,7 +6242,7 @@
STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
COPY_ASCII | DEST_ALWAYS_ALIGNED);
- __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+ __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
__ add(sp, sp, Operand(3 * kPointerSize));
__ Ret();
@@ -6273,7 +6274,7 @@
STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
StringHelper::GenerateCopyCharactersLong(
masm, r1, r5, r2, r3, r4, r6, r7, r9, DEST_ALWAYS_ALIGNED);
- __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+ __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
__ add(sp, sp, Operand(3 * kPointerSize));
__ Ret();
@@ -6345,6 +6346,8 @@
void StringCompareStub::Generate(MacroAssembler* masm) {
Label runtime;
+ Counters* counters = masm->isolate()->counters();
+
// Stack frame on entry.
// sp[0]: right string
// sp[4]: left string
@@ -6356,7 +6359,7 @@
STATIC_ASSERT(EQUAL == 0);
STATIC_ASSERT(kSmiTag == 0);
__ mov(r0, Operand(Smi::FromInt(EQUAL)));
- __ IncrementCounter(COUNTERS->string_compare_native(), 1, r1, r2);
+ __ IncrementCounter(counters->string_compare_native(), 1, r1, r2);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Ret();
@@ -6366,7 +6369,7 @@
__ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime);
// Compare flat ASCII strings natively. Remove arguments from stack first.
- __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3);
+ __ IncrementCounter(counters->string_compare_native(), 1, r2, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
@@ -6381,6 +6384,8 @@
Label string_add_runtime, call_builtin;
Builtins::JavaScript builtin_id = Builtins::ADD;
+ Counters* counters = masm->isolate()->counters();
+
// Stack on entry:
// sp[0]: second argument (right).
// sp[4]: first argument (left).
@@ -6436,7 +6441,7 @@
__ cmp(r3, Operand(Smi::FromInt(0)), ne);
__ b(ne, &strings_not_empty); // If either string was empty, return r0.
- __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+ __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Ret();
@@ -6481,7 +6486,7 @@
Label make_two_character_string;
StringHelper::GenerateTwoCharacterSymbolTableProbe(
masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string);
- __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+ __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Ret();
@@ -6494,7 +6499,7 @@
__ mov(r6, Operand(2));
__ AllocateAsciiString(r0, r6, r4, r5, r9, &string_add_runtime);
__ strh(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
- __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+ __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Ret();
@@ -6531,7 +6536,7 @@
__ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
__ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
__ mov(r0, Operand(r7));
- __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+ __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Ret();
@@ -6613,7 +6618,7 @@
// r7: result string.
StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, true);
__ mov(r0, Operand(r7));
- __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+ __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Ret();
@@ -6654,7 +6659,7 @@
StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false);
__ mov(r0, Operand(r7));
- __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+ __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
__ add(sp, sp, Operand(2 * kPointerSize));
__ Ret();
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 5e3b7d0..91c4747 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -1787,7 +1787,7 @@
__ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE);
__ b(ne, &build_args);
Handle<Code> apply_code(
- Isolate::Current()->builtins()->builtin(Builtins::FunctionApply));
+ Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply));
__ ldr(r1, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
__ sub(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
__ cmp(r1, Operand(apply_code));
@@ -3632,7 +3632,7 @@
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Initialize));
+ Builtins::kStoreIC_Initialize));
Load(value);
if (property->emit_store()) {
frame_->PopToR0();
@@ -3699,7 +3699,8 @@
FastCloneShallowArrayStub stub(
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
frame_->CallStub(&stub, 3);
- __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1, r1, r2);
+ __ IncrementCounter(masm_->isolate()->counters()->cow_arrays_created_stub(),
+ 1, r1, r2);
} else if (node->depth() > 1) {
frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
} else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
@@ -4460,7 +4461,7 @@
// constructor invocation.
CodeForSourcePosition(node->position());
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Builtins::kJSConstructCall));
frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1);
frame_->EmitPush(r0);
@@ -6588,9 +6589,10 @@
Register scratch1 = VirtualFrame::scratch0();
Register scratch2 = VirtualFrame::scratch1();
ASSERT(!receiver_.is(scratch1) && !receiver_.is(scratch2));
- __ DecrementCounter(COUNTERS->named_load_inline(), 1, scratch1, scratch2);
- __ IncrementCounter(COUNTERS->named_load_inline_miss(), 1,
- scratch1, scratch2);
+ __ DecrementCounter(masm_->isolate()->counters()->named_load_inline(),
+ 1, scratch1, scratch2);
+ __ IncrementCounter(masm_->isolate()->counters()->named_load_inline_miss(),
+ 1, scratch1, scratch2);
// Ensure receiver in r0 and name in r2 to match load ic calling convention.
__ Move(r0, receiver_);
@@ -6599,7 +6601,7 @@
// The rest of the instructions in the deferred code must be together.
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Builtins::kLoadIC_Initialize));
RelocInfo::Mode mode = is_contextual_
? RelocInfo::CODE_TARGET_CONTEXT
: RelocInfo::CODE_TARGET;
@@ -6661,9 +6663,10 @@
Register scratch1 = VirtualFrame::scratch0();
Register scratch2 = VirtualFrame::scratch1();
- __ DecrementCounter(COUNTERS->keyed_load_inline(), 1, scratch1, scratch2);
- __ IncrementCounter(COUNTERS->keyed_load_inline_miss(),
- 1, scratch1, scratch2);
+ __ DecrementCounter(masm_->isolate()->counters()->keyed_load_inline(),
+ 1, scratch1, scratch2);
+ __ IncrementCounter(masm_->isolate()->counters()->keyed_load_inline_miss(),
+ 1, scratch1, scratch2);
// Ensure key in r0 and receiver in r1 to match keyed load ic calling
// convention.
@@ -6675,7 +6678,7 @@
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
// Call keyed load IC. It has the arguments key and receiver in r0 and r1.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Builtins::kKeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
// keyed load has been inlined.
@@ -6722,8 +6725,9 @@
void DeferredReferenceSetKeyedValue::Generate() {
Register scratch1 = VirtualFrame::scratch0();
Register scratch2 = VirtualFrame::scratch1();
- __ DecrementCounter(COUNTERS->keyed_store_inline(), 1, scratch1, scratch2);
- __ IncrementCounter(COUNTERS->keyed_store_inline_miss(),
+ __ DecrementCounter(masm_->isolate()->counters()->keyed_store_inline(),
+ 1, scratch1, scratch2);
+ __ IncrementCounter(masm_->isolate()->counters()->keyed_store_inline_miss(),
1, scratch1, scratch2);
// Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic
@@ -6738,8 +6742,9 @@
// Call keyed store IC. It has the arguments value, key and receiver in r0,
// r1 and r2.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ (strict_mode_ == kStrictMode)
+ ? Builtins::kKeyedStoreIC_Initialize_Strict
+ : Builtins::kKeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
// keyed store has been inlined.
@@ -6793,8 +6798,8 @@
// Call keyed store IC. It has the arguments value, key and receiver in r0,
// r1 and r2.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode_ == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ (strict_mode_ == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+ : Builtins::kStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
// named store has been inlined.
@@ -6840,11 +6845,12 @@
// Counter will be decremented in the deferred code. Placed here to avoid
// having it in the instruction stream below where patching will occur.
if (is_contextual) {
- __ IncrementCounter(COUNTERS->named_load_global_inline(), 1,
- frame_->scratch0(), frame_->scratch1());
+ __ IncrementCounter(
+ masm_->isolate()->counters()->named_load_global_inline(),
+ 1, frame_->scratch0(), frame_->scratch1());
} else {
- __ IncrementCounter(COUNTERS->named_load_inline(), 1,
- frame_->scratch0(), frame_->scratch1());
+ __ IncrementCounter(masm_->isolate()->counters()->named_load_inline(),
+ 1, frame_->scratch0(), frame_->scratch1());
}
// The following instructions are the inlined load of an in-object property.
@@ -6876,8 +6882,9 @@
}
}
if (is_dont_delete) {
- __ IncrementCounter(COUNTERS->dont_delete_hint_hit(), 1,
- frame_->scratch0(), frame_->scratch1());
+ __ IncrementCounter(
+ masm_->isolate()->counters()->dont_delete_hint_hit(),
+ 1, frame_->scratch0(), frame_->scratch1());
}
}
@@ -7062,8 +7069,8 @@
// Counter will be decremented in the deferred code. Placed here to avoid
// having it in the instruction stream below where patching will occur.
- __ IncrementCounter(COUNTERS->keyed_load_inline(), 1,
- frame_->scratch0(), frame_->scratch1());
+ __ IncrementCounter(masm_->isolate()->counters()->keyed_load_inline(),
+ 1, frame_->scratch0(), frame_->scratch1());
// Load the key and receiver from the stack.
bool key_is_known_smi = frame_->KnownSmiAt(0);
@@ -7149,8 +7156,8 @@
// Counter will be decremented in the deferred code. Placed here to avoid
// having it in the instruction stream below where patching will occur.
- __ IncrementCounter(COUNTERS->keyed_store_inline(), 1,
- scratch1, scratch2);
+ __ IncrementCounter(masm_->isolate()->counters()->keyed_store_inline(),
+ 1, scratch1, scratch2);
// Load the value, key and receiver from the stack.
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index f1fde92..33ca3b0 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -44,6 +44,11 @@
}
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+ // Nothing to do. No new relocation information is written for lazy
+ // deoptimization on ARM.
+}
+
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
HandleScope scope;
@@ -106,7 +111,7 @@
// Add the deoptimizing code to the list.
DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
- DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
+ DeoptimizerData* data = code->GetIsolate()->deoptimizer_data();
node->set_next(data->deoptimizing_code_list_);
data->deoptimizing_code_list_ = node;
@@ -316,8 +321,7 @@
optimized_code_->entry() + pc_offset);
output_[0]->SetPc(pc);
}
- Code* continuation = Isolate::Current()->builtins()->builtin(
- Builtins::NotifyOSR);
+ Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
output_[0]->SetContinuation(
reinterpret_cast<uint32_t>(continuation->entry()));
@@ -496,8 +500,8 @@
if (is_topmost) {
Builtins* builtins = isolate_->builtins();
Code* continuation = (bailout_type_ == EAGER)
- ? builtins->builtin(Builtins::NotifyDeoptimized)
- : builtins->builtin(Builtins::NotifyLazyDeoptimized);
+ ? builtins->builtin(Builtins::kNotifyDeoptimized)
+ : builtins->builtin(Builtins::kNotifyLazyDeoptimized);
output_frame->SetContinuation(
reinterpret_cast<uint32_t>(continuation->entry()));
}
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 2edfd0a..088ba58 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -781,9 +781,9 @@
prop->key()->AsLiteral()->handle()->IsSmi());
__ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
- Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
- ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Value in r0 is ignored (declarations are statements).
}
@@ -1186,8 +1186,8 @@
ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
slow));
__ mov(r0, Operand(key_literal->handle()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic =
+ isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ jmp(done);
}
@@ -1253,8 +1253,7 @@
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
EmitCallIC(ic, mode);
}
@@ -1272,8 +1271,7 @@
// object (receiver) in r0.
__ ldr(r0, GlobalObjectOperand());
__ mov(r2, Operand(var->name()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
context()->Plug(r0);
@@ -1332,8 +1330,7 @@
__ mov(r0, Operand(key_literal->handle()));
// Call keyed load IC. It has arguments key and receiver in r0 and r1.
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
context()->Plug(r0);
}
@@ -1442,8 +1439,7 @@
VisitForAccumulatorValue(value);
__ mov(r2, Operand(key->handle()));
__ ldr(r1, MemOperand(sp));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::StoreIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
@@ -1698,8 +1694,7 @@
Literal* key = prop->key()->AsLiteral();
__ mov(r2, Operand(key->handle()));
// Call load IC. It has arguments receiver and property name r0 and r2.
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
@@ -1707,8 +1702,7 @@
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has arguments key and receiver in r0 and r1.
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
@@ -1853,9 +1847,9 @@
__ mov(r1, r0);
__ pop(r0); // Restore value.
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
break;
}
@@ -1876,9 +1870,9 @@
__ pop(r2);
}
__ pop(r0); // Restore value.
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
break;
}
@@ -1902,9 +1896,9 @@
// r2, and the global object in r1.
__ mov(r2, Operand(var->name()));
__ ldr(r1, GlobalObjectOperand());
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
} else if (op == Token::INIT_CONST) {
@@ -2011,9 +2005,9 @@
__ pop(r1);
}
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case.
@@ -2057,9 +2051,9 @@
__ pop(r2);
}
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case.
@@ -2344,8 +2338,7 @@
// Record source code position for IC call.
SetSourcePosition(prop->position());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ ldr(r1, GlobalObjectOperand());
__ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
@@ -2413,8 +2406,8 @@
__ mov(r0, Operand(arg_count));
__ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
- Handle<Code> construct_builtin(isolate()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Handle<Code> construct_builtin =
+ isolate()->builtins()->JSConstructCall();
__ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
context()->Plug(r0);
}
@@ -3914,9 +3907,9 @@
case NAMED_PROPERTY: {
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
__ pop(r1);
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -3931,9 +3924,9 @@
case KEYED_PROPERTY: {
__ pop(r1); // Key.
__ pop(r2); // Receiver.
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -3957,8 +3950,7 @@
Comment cmnt(masm_, "Global variable");
__ ldr(r0, GlobalObjectOperand());
__ mov(r2, Operand(proxy->name()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
// Use a regular load, not a contextual load, to avoid a reference
// error.
EmitCallIC(ic, RelocInfo::CODE_TARGET);
@@ -4229,18 +4221,19 @@
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT);
+ Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
- __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2);
+ __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
break;
case Code::KEYED_LOAD_IC:
- __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2);
+ __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
break;
case Code::STORE_IC:
- __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2);
+ __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
break;
case Code::KEYED_STORE_IC:
- __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2);
+ __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
default:
break;
}
@@ -4250,18 +4243,19 @@
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
+ Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
- __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2);
+ __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
break;
case Code::KEYED_LOAD_IC:
- __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2);
+ __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
break;
case Code::STORE_IC:
- __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2);
+ __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
break;
case Code::KEYED_STORE_IC:
- __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2);
+ __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
default:
break;
}
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 9f9b63c..dc4f761 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -646,11 +646,12 @@
// -- r2 : name
// -- lr : return address
// -----------------------------------
+ Isolate* isolate = masm->isolate();
if (id == IC::kCallIC_Miss) {
- __ IncrementCounter(COUNTERS->call_miss(), 1, r3, r4);
+ __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4);
} else {
- __ IncrementCounter(COUNTERS->keyed_call_miss(), 1, r3, r4);
+ __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4);
}
// Get the receiver of the function from the stack.
@@ -663,7 +664,7 @@
// Call the entry.
__ mov(r0, Operand(2));
- __ mov(r1, Operand(ExternalReference(IC_Utility(id), masm->isolate())));
+ __ mov(r1, Operand(ExternalReference(IC_Utility(id), isolate)));
CEntryStub stub(1);
__ CallStub(&stub);
@@ -765,7 +766,8 @@
GenerateFastArrayLoad(
masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load);
- __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1, r0, r3);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1, r0, r3);
__ bind(&do_call);
// receiver in r1 is not used after this point.
@@ -784,13 +786,13 @@
__ mov(r0, Operand(r2, ASR, kSmiTagSize));
// r0: untagged index
GenerateNumberDictionaryLoad(masm, &slow_load, r4, r2, r1, r0, r3, r5);
- __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1, r0, r3);
+ __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3);
__ jmp(&do_call);
__ bind(&slow_load);
// This branch is taken when calling KeyedCallIC_Miss is neither required
// nor beneficial.
- __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1, r0, r3);
+ __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, r0, r3);
__ EnterInternalFrame();
__ push(r2); // save the key
__ Push(r1, r2); // pass the receiver and the key
@@ -817,11 +819,11 @@
__ b(ne, &lookup_monomorphic_cache);
GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4);
- __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1, r0, r3);
+ __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3);
__ jmp(&do_call);
__ bind(&lookup_monomorphic_cache);
- __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1, r0, r3);
+ __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3);
GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
// Fall through on miss.
@@ -832,7 +834,7 @@
// - the value loaded is not a function,
// - there is hope that the runtime will create a monomorphic call stub
// that will get fetched next time.
- __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1, r0, r3);
+ __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3);
GenerateMiss(masm, argc);
__ bind(&index_string);
@@ -911,15 +913,16 @@
// -- r0 : receiver
// -- sp[0] : receiver
// -----------------------------------
+ Isolate* isolate = masm->isolate();
- __ IncrementCounter(COUNTERS->load_miss(), 1, r3, r4);
+ __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4);
__ mov(r3, r0);
__ Push(r3, r2);
// Perform tail call to the entry.
ExternalReference ref =
- ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
+ ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
__ TailCallExternalReference(ref, 2, 1);
}
@@ -965,7 +968,7 @@
// Find the end of the inlined code for handling the load if this is an
// inlined IC call site.
- Address inline_end_address;
+ Address inline_end_address = 0;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
@@ -1005,7 +1008,7 @@
bool is_dont_delete) {
// Find the end of the inlined code for handling the contextual load if
// this is inlined IC call site.
- Address inline_end_address;
+ Address inline_end_address = 0;
int marker = InlinedICSiteMarker(address, &inline_end_address);
if (!((marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT) ||
(marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE))) {
@@ -1046,7 +1049,7 @@
// Find the end of the inlined code for the store if there is an
// inlined version of the store.
- Address inline_end_address;
+ Address inline_end_address = 0;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
@@ -1096,7 +1099,7 @@
bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
if (V8::UseCrankshaft()) return false;
- Address inline_end_address;
+ Address inline_end_address = 0;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
@@ -1118,7 +1121,7 @@
// Find the end of the inlined code for handling the store if this is an
// inlined IC call site.
- Address inline_end_address;
+ Address inline_end_address = 0;
if (InlinedICSiteMarker(address, &inline_end_address)
!= Assembler::PROPERTY_ACCESS_INLINED) {
return false;
@@ -1144,13 +1147,14 @@
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
+ Isolate* isolate = masm->isolate();
- __ IncrementCounter(COUNTERS->keyed_load_miss(), 1, r3, r4);
+ __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4);
__ Push(r1, r0);
ExternalReference ref =
- ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
+ ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
__ TailCallExternalReference(ref, 2, 1);
}
@@ -1180,6 +1184,8 @@
Register key = r0;
Register receiver = r1;
+ Isolate* isolate = masm->isolate();
+
// Check that the key is a smi.
__ JumpIfNotSmi(key, &check_string);
__ bind(&index_smi);
@@ -1197,7 +1203,7 @@
GenerateFastArrayLoad(
masm, receiver, key, r4, r3, r2, r0, NULL, &slow);
- __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1, r2, r3);
+ __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r2, r3);
__ Ret();
__ bind(&check_number_dictionary);
@@ -1217,7 +1223,8 @@
// Slow case, key and receiver still in r0 and r1.
__ bind(&slow);
- __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1, r2, r3);
+ __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
+ 1, r2, r3);
GenerateRuntimeGetProperty(masm);
__ bind(&check_string);
@@ -1245,7 +1252,7 @@
// Load the key (consisting of map and symbol) from the cache and
// check for match.
ExternalReference cache_keys =
- ExternalReference::keyed_lookup_cache_keys(masm->isolate());
+ ExternalReference::keyed_lookup_cache_keys(isolate);
__ mov(r4, Operand(cache_keys));
__ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1));
__ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); // Move r4 to symbol.
@@ -1261,7 +1268,7 @@
// r2 : receiver's map
// r3 : lookup cache index
ExternalReference cache_field_offsets =
- ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
+ ExternalReference::keyed_lookup_cache_field_offsets(isolate);
__ mov(r4, Operand(cache_field_offsets));
__ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2));
__ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset));
@@ -1273,7 +1280,8 @@
__ add(r6, r6, r5); // Index from start of object.
__ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag.
__ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2));
- __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3);
+ __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
+ 1, r2, r3);
__ Ret();
// Load property array property.
@@ -1281,7 +1289,8 @@
__ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset));
__ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2));
- __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3);
+ __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
+ 1, r2, r3);
__ Ret();
// Do a quick inline probe of the receiver's dictionary, if it
@@ -1295,7 +1304,8 @@
GenerateGlobalInstanceTypeCheck(masm, r2, &slow);
// Load the property to r0.
GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4);
- __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1, r2, r3);
+ __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(),
+ 1, r2, r3);
__ Ret();
__ bind(&index_string);
@@ -1625,11 +1635,13 @@
GenerateStringDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss);
GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5);
- __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->store_normal_hit(),
+ 1, r4, r5);
__ Ret();
__ bind(&miss);
- __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5);
+ __ IncrementCounter(counters->store_normal_miss(), 1, r4, r5);
GenerateMiss(masm);
}
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 3446995..5d31473 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1769,6 +1769,21 @@
}
+LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
+ HLoadNamedFieldPolymorphic* instr) {
+ ASSERT(instr->representation().IsTagged());
+ if (instr->need_generic()) {
+ LOperand* obj = UseFixed(instr->object(), r0);
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+ return MarkAsCall(DefineFixed(result, r0), instr);
+ } else {
+ LOperand* obj = UseRegisterAtStart(instr->object());
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+ return AssignEnvironment(DefineAsRegister(result));
+ }
+}
+
+
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* object = UseFixed(instr->object(), r0);
LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), r0);
@@ -1807,15 +1822,22 @@
}
-LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
- HLoadPixelArrayElement* instr) {
+LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
+ HLoadKeyedSpecializedArrayElement* instr) {
+ // TODO(danno): Add support for other external array types.
+ if (instr->array_type() != kExternalPixelArray) {
+ Abort("unsupported load for external array type.");
+ return NULL;
+ }
+
ASSERT(instr->representation().IsInteger32());
ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer =
UseRegisterAtStart(instr->external_pointer());
LOperand* key = UseRegisterAtStart(instr->key());
- LLoadPixelArrayElement* result =
- new LLoadPixelArrayElement(external_pointer, key);
+ LLoadKeyedSpecializedArrayElement* result =
+ new LLoadKeyedSpecializedArrayElement(external_pointer,
+ key);
return DefineAsRegister(result);
}
@@ -1849,8 +1871,14 @@
}
-LInstruction* LChunkBuilder::DoStorePixelArrayElement(
- HStorePixelArrayElement* instr) {
+LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
+ HStoreKeyedSpecializedArrayElement* instr) {
+ // TODO(danno): Add support for other external array types.
+ if (instr->array_type() != kExternalPixelArray) {
+ Abort("unsupported store for external array type.");
+ return NULL;
+ }
+
ASSERT(instr->value()->representation().IsInteger32());
ASSERT(instr->external_pointer()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32());
@@ -1859,7 +1887,9 @@
LOperand* value = UseTempRegister(instr->value()); // changed by clamp.
LOperand* key = UseRegister(instr->key());
- return new LStorePixelArrayElement(external_pointer, key, value);
+ return new LStoreKeyedSpecializedArrayElement(external_pointer,
+ key,
+ value);
}
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 50650c1..77aabaf 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -122,9 +122,10 @@
V(LoadGlobal) \
V(LoadKeyedFastElement) \
V(LoadKeyedGeneric) \
+ V(LoadKeyedSpecializedArrayElement) \
V(LoadNamedField) \
+ V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
- V(LoadPixelArrayElement) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@@ -146,9 +147,9 @@
V(StoreGlobal) \
V(StoreKeyedFastElement) \
V(StoreKeyedGeneric) \
+ V(StoreKeyedSpecializedArrayElement) \
V(StoreNamedField) \
V(StoreNamedGeneric) \
- V(StorePixelArrayElement) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
V(StringLength) \
@@ -1148,6 +1149,19 @@
};
+class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LLoadNamedFieldPolymorphic(LOperand* object) {
+ inputs_[0] = object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
+ DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
+
+ LOperand* object() { return inputs_[0]; }
+};
+
+
class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
public:
explicit LLoadNamedGeneric(LOperand* object) {
@@ -1211,19 +1225,23 @@
};
-class LLoadPixelArrayElement: public LTemplateInstruction<1, 2, 0> {
+class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
public:
- LLoadPixelArrayElement(LOperand* external_pointer, LOperand* key) {
+ LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
+ LOperand* key) {
inputs_[0] = external_pointer;
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
- "load-pixel-array-element")
- DECLARE_HYDROGEN_ACCESSOR(LoadPixelArrayElement)
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+ "load-keyed-specialized-array-element")
+ DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+ ExternalArrayType array_type() const {
+ return hydrogen()->array_type();
+ }
};
@@ -1628,25 +1646,29 @@
LOperand* value() { return inputs_[2]; }
};
-class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
public:
- LStorePixelArrayElement(LOperand* external_pointer,
- LOperand* key,
- LOperand* val) {
+ LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
+ LOperand* key,
+ LOperand* val) {
inputs_[0] = external_pointer;
inputs_[1] = key;
inputs_[2] = val;
}
- DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
- "store-pixel-array-element")
- DECLARE_HYDROGEN_ACCESSOR(StorePixelArrayElement)
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+ "store-keyed-specialized-array-element")
+ DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+ ExternalArrayType array_type() const {
+ return hydrogen()->array_type();
+ }
};
+
class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
public:
LStringCharCodeAt(LOperand* string, LOperand* index) {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 48a9f7f..75406cf 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -94,6 +94,7 @@
code->set_stack_slots(StackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
PopulateDeoptimizationData(code);
+ Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
}
@@ -1085,16 +1086,25 @@
ASSERT(left->Equals(instr->result()));
ASSERT(left->IsRegister());
Register result = ToRegister(left);
- Register right_reg = EmitLoadRegister(right, ip);
+ Operand right_operand(no_reg);
+
+ if (right->IsStackSlot() || right->IsArgument()) {
+ Register right_reg = EmitLoadRegister(right, ip);
+ right_operand = Operand(right_reg);
+ } else {
+ ASSERT(right->IsRegister() || right->IsConstantOperand());
+ right_operand = ToOperand(right);
+ }
+
switch (instr->op()) {
case Token::BIT_AND:
- __ and_(result, ToRegister(left), Operand(right_reg));
+ __ and_(result, ToRegister(left), right_operand);
break;
case Token::BIT_OR:
- __ orr(result, ToRegister(left), Operand(right_reg));
+ __ orr(result, ToRegister(left), right_operand);
break;
case Token::BIT_XOR:
- __ eor(result, ToRegister(left), Operand(right_reg));
+ __ eor(result, ToRegister(left), right_operand);
break;
default:
UNREACHABLE();
@@ -1163,11 +1173,21 @@
void LCodeGen::DoSubI(LSubI* instr) {
- Register left = ToRegister(instr->InputAt(0));
- Register right = EmitLoadRegister(instr->InputAt(1), ip);
- ASSERT(instr->InputAt(0)->Equals(instr->result()));
- __ sub(left, left, right, SetCC);
- if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ LOperand* left = instr->InputAt(0);
+ LOperand* right = instr->InputAt(1);
+ ASSERT(left->Equals(instr->result()));
+ bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+ SBit set_cond = can_overflow ? SetCC : LeaveCC;
+
+ if (right->IsStackSlot() || right->IsArgument()) {
+ Register right_reg = EmitLoadRegister(right, ip);
+ __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
+ } else {
+ ASSERT(right->IsRegister() || right->IsConstantOperand());
+ __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
+ }
+
+ if (can_overflow) {
DeoptimizeIf(vs, instr->environment());
}
}
@@ -1256,11 +1276,18 @@
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
ASSERT(left->Equals(instr->result()));
+ bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+ SBit set_cond = can_overflow ? SetCC : LeaveCC;
- Register right_reg = EmitLoadRegister(right, ip);
- __ add(ToRegister(left), ToRegister(left), Operand(right_reg), SetCC);
+ if (right->IsStackSlot() || right->IsArgument()) {
+ Register right_reg = EmitLoadRegister(right, ip);
+ __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
+ } else {
+ ASSERT(right->IsRegister() || right->IsConstantOperand());
+ __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
+ }
- if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ if (can_overflow) {
DeoptimizeIf(vs, instr->environment());
}
}
@@ -2203,14 +2230,77 @@
}
+void LCodeGen::EmitLoadField(Register result,
+ Register object,
+ Handle<Map> type,
+ Handle<String> name) {
+ LookupResult lookup;
+ type->LookupInDescriptors(NULL, *name, &lookup);
+ ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
+ int index = lookup.GetLocalFieldIndexFromMap(*type);
+ int offset = index * kPointerSize;
+ if (index < 0) {
+ // Negative property indices are in-object properties, indexed
+ // from the end of the fixed part of the object.
+ __ ldr(result, FieldMemOperand(object, offset + type->instance_size()));
+ } else {
+ // Non-negative property indices are in the properties array.
+ __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
+ __ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
+ }
+}
+
+
+void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
+ Register object = ToRegister(instr->object());
+ Register result = ToRegister(instr->result());
+ Register scratch = scratch0();
+ int map_count = instr->hydrogen()->types()->length();
+ Handle<String> name = instr->hydrogen()->name();
+ if (map_count == 0) {
+ ASSERT(instr->hydrogen()->need_generic());
+ __ mov(r2, Operand(name));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ } else {
+ Label done;
+ __ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+ for (int i = 0; i < map_count - 1; ++i) {
+ Handle<Map> map = instr->hydrogen()->types()->at(i);
+ Label next;
+ __ cmp(scratch, Operand(map));
+ __ b(ne, &next);
+ EmitLoadField(result, object, map, name);
+ __ b(&done);
+ __ bind(&next);
+ }
+ Handle<Map> map = instr->hydrogen()->types()->last();
+ __ cmp(scratch, Operand(map));
+ if (instr->hydrogen()->need_generic()) {
+ Label generic;
+ __ b(ne, &generic);
+ EmitLoadField(result, object, map, name);
+ __ b(&done);
+ __ bind(&generic);
+ __ mov(r2, Operand(name));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ } else {
+ DeoptimizeIf(ne, instr->environment());
+ EmitLoadField(result, object, map, name);
+ }
+ __ bind(&done);
+ }
+}
+
+
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->object()).is(r0));
ASSERT(ToRegister(instr->result()).is(r0));
// Name is always in r2.
__ mov(r2, Operand(instr->name()));
- Handle<Code> ic(
- isolate()->builtins()->builtin(Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2327,7 +2417,10 @@
}
-void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
+void LCodeGen::DoLoadKeyedSpecializedArrayElement(
+ LLoadKeyedSpecializedArrayElement* instr) {
+ ASSERT(instr->array_type() == kExternalPixelArray);
+
Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
Register result = ToRegister(instr->result());
@@ -2341,8 +2434,7 @@
ASSERT(ToRegister(instr->object()).is(r1));
ASSERT(ToRegister(instr->key()).is(r0));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2908,8 +3000,7 @@
ASSERT(ToRegister(instr->InputAt(0)).is(r1));
ASSERT(ToRegister(instr->result()).is(r0));
- Handle<Code> builtin(isolate()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
__ mov(r0, Operand(instr->arity()));
CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -2958,9 +3049,9 @@
// Name is always in r2.
__ mov(r2, Operand(instr->name()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- info_->is_strict() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = info_->is_strict()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2997,7 +3088,10 @@
}
-void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) {
+void LCodeGen::DoStoreKeyedSpecializedArrayElement(
+ LStoreKeyedSpecializedArrayElement* instr) {
+ ASSERT(instr->array_type() == kExternalPixelArray);
+
Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
Register value = ToRegister(instr->value());
@@ -3013,9 +3107,9 @@
ASSERT(ToRegister(instr->key()).is(r1));
ASSERT(ToRegister(instr->value()).is(r0));
- Handle<Code> ic(isolate()->builtins()->builtin(
- info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = info_->is_strict()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index da34176..caa85d2 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -264,6 +264,11 @@
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp1, Register temp2);
+ void EmitLoadField(Register result,
+ Register object,
+ Handle<Map> type,
+ Handle<String> name);
+
LChunk* const chunk_;
MacroAssembler* const masm_;
CompilationInfo* const info_;
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 626c46f..3a1a8b6 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -903,8 +903,7 @@
}
Handle<Code> adaptor =
- Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::ArgumentsAdaptorTrampoline));
+ isolate()->builtins()->ArgumentsAdaptorTrampoline();
if (flag == CALL_FUNCTION) {
if (call_wrapper != NULL) {
call_wrapper->BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index c548aab..30f1b38 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -102,8 +102,9 @@
Register scratch0,
Register scratch1) {
ASSERT(name->IsSymbol());
- __ IncrementCounter(COUNTERS->negative_lookups(), 1, scratch0, scratch1);
- __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1, scratch0, scratch1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
+ __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
Label done;
@@ -199,7 +200,7 @@
}
}
__ bind(&done);
- __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1, scratch0, scratch1);
+ __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
}
@@ -210,7 +211,7 @@
Register scratch,
Register extra,
Register extra2) {
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = masm->isolate();
Label miss;
// Make sure that code is valid. The shifting code relies on the
@@ -288,14 +289,15 @@
void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
MacroAssembler* masm, int index, Register prototype, Label* miss) {
+ Isolate* isolate = masm->isolate();
// Check we're still in the same context.
__ ldr(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ Move(ip, Isolate::Current()->global());
+ __ Move(ip, isolate->global());
__ cmp(prototype, ip);
__ b(ne, miss);
// Get the global function with the given index.
- JSFunction* function = JSFunction::cast(
- Isolate::Current()->global_context()->get(index));
+ JSFunction* function =
+ JSFunction::cast(isolate->global_context()->get(index));
// Load its initial map. The global functions all have initial maps.
__ Move(prototype, Handle<Map>(function->initial_map()));
// Load the prototype from the initial map.
@@ -510,9 +512,9 @@
ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
Code* code = NULL;
if (kind == Code::LOAD_IC) {
- code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss);
+ code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
} else {
- code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
+ code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
}
Handle<Code> ic(code);
@@ -736,6 +738,8 @@
ASSERT(optimization.is_constant_call());
ASSERT(!lookup->holder()->IsGlobalObject());
+ Counters* counters = masm->isolate()->counters();
+
int depth1 = kInvalidProtoDepth;
int depth2 = kInvalidProtoDepth;
bool can_do_fast_api_call = false;
@@ -753,11 +757,11 @@
(depth2 != kInvalidProtoDepth);
}
- __ IncrementCounter(COUNTERS->call_const_interceptor(), 1,
+ __ IncrementCounter(counters->call_const_interceptor(), 1,
scratch1, scratch2);
if (can_do_fast_api_call) {
- __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1,
+ __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1,
scratch1, scratch2);
ReserveSpaceForFastApiCall(masm, scratch1);
}
@@ -949,7 +953,7 @@
Register fval,
Register scratch1,
Register scratch2) {
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ if (masm->isolate()->cpu_features()->IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
__ vmov(s0, ival);
__ add(scratch1, dst, Operand(wordoffset, LSL, 2));
@@ -1161,7 +1165,7 @@
__ b(ne, miss);
// Log the check depth.
- LOG(Isolate::Current(), IntEvent("check-maps-depth", depth + 1));
+ LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
// Perform security check for access to the global object.
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
@@ -1497,7 +1501,7 @@
MaybeObject* CallStubCompiler::GenerateMissBranch() {
- MaybeObject* maybe_obj = Isolate::Current()->stub_cache()->ComputeCallMiss(
+ MaybeObject* maybe_obj = masm()->isolate()->stub_cache()->ComputeCallMiss(
arguments().immediate(), kind_);
Object* obj;
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
@@ -2044,7 +2048,7 @@
// -- sp[argc * 4] : receiver
// -----------------------------------
- if (!Isolate::Current()->cpu_features()->IsSupported(VFP3))
+ if (!masm()->isolate()->cpu_features()->IsSupported(VFP3))
return HEAP->undefined_value();
CpuFeatures::Scope scope_vfp3(VFP3);
@@ -2287,14 +2291,18 @@
JSGlobalPropertyCell* cell,
JSFunction* function,
String* name) {
+ Isolate* isolate = masm()->isolate();
+ Heap* heap = isolate->heap();
+ Counters* counters = isolate->counters();
+
ASSERT(optimization.is_simple_api_call());
// Bail out if object is a global object as we don't want to
// repatch it to global receiver.
- if (object->IsGlobalObject()) return HEAP->undefined_value();
- if (cell != NULL) return HEAP->undefined_value();
+ if (object->IsGlobalObject()) return heap->undefined_value();
+ if (cell != NULL) return heap->undefined_value();
int depth = optimization.GetPrototypeDepthOfExpectedType(
JSObject::cast(object), holder);
- if (depth == kInvalidProtoDepth) return HEAP->undefined_value();
+ if (depth == kInvalidProtoDepth) return heap->undefined_value();
Label miss, miss_before_stack_reserved;
@@ -2308,8 +2316,8 @@
__ tst(r1, Operand(kSmiTagMask));
__ b(eq, &miss_before_stack_reserved);
- __ IncrementCounter(COUNTERS->call_const(), 1, r0, r3);
- __ IncrementCounter(COUNTERS->call_const_fast_api(), 1, r0, r3);
+ __ IncrementCounter(counters->call_const(), 1, r0, r3);
+ __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3);
ReserveSpaceForFastApiCall(masm(), r0);
@@ -2371,7 +2379,8 @@
SharedFunctionInfo* function_info = function->shared();
switch (check) {
case RECEIVER_MAP_CHECK:
- __ IncrementCounter(COUNTERS->call_const(), 1, r0, r3);
+ __ IncrementCounter(masm()->isolate()->counters()->call_const(),
+ 1, r0, r3);
// Check that the maps haven't changed.
CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
@@ -2558,7 +2567,8 @@
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
- __ IncrementCounter(COUNTERS->call_global_inline(), 1, r3, r4);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->call_global_inline(), 1, r3, r4);
ASSERT(function->is_compiled());
Handle<Code> code(function->code());
ParameterCount expected(function->shared()->formal_parameter_count());
@@ -2575,7 +2585,7 @@
// Handle call cache miss.
__ bind(&miss);
- __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1, r1, r3);
+ __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3);
MaybeObject* maybe_result = GenerateMissBranch();
if (maybe_result->IsFailure()) return maybe_result;
@@ -2603,8 +2613,7 @@
r1, r2, r3,
&miss);
__ bind(&miss);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2653,8 +2662,7 @@
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2703,8 +2711,7 @@
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2741,14 +2748,14 @@
// Store the value in the cell.
__ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset));
- __ IncrementCounter(COUNTERS->named_store_global_inline(), 1, r4, r3);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3);
__ Ret();
// Handle store cache miss.
__ bind(&miss);
- __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1, r4, r3);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3);
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2930,11 +2937,12 @@
}
__ mov(r0, r4);
- __ IncrementCounter(COUNTERS->named_load_global_stub(), 1, r1, r3);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
__ Ret();
__ bind(&miss);
- __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1, r1, r3);
+ __ IncrementCounter(counters->named_load_global_stub_miss(), 1, r1, r3);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
@@ -3079,7 +3087,9 @@
// -- r1 : receiver
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1, r2, r3);
+
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_string_length(), 1, r2, r3);
// Check the key is the cached one.
__ cmp(r0, Operand(Handle<String>(name)));
@@ -3087,7 +3097,7 @@
GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1, r2, r3);
+ __ DecrementCounter(counters->keyed_load_string_length(), 1, r2, r3);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -3103,7 +3113,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1, r2, r3);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
// Check the name hasn't changed.
__ cmp(r0, Operand(Handle<String>(name)));
@@ -3111,7 +3122,7 @@
GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1, r2, r3);
+ __ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
return GetCode(CALLBACKS, name);
@@ -3179,7 +3190,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_store_field(), 1, r3, r4);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4);
// Check that the name has not changed.
__ cmp(r1, Operand(Handle<String>(name)));
@@ -3195,10 +3207,8 @@
&miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_store_field(), 1, r3, r4);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_Miss));
-
+ __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4);
+ Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -3268,8 +3278,7 @@
__ Ret();
__ bind(&miss);
- Handle<Code> ic(
- Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -3405,17 +3414,16 @@
// Remove caller arguments and receiver from the stack and return.
__ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2));
__ add(sp, sp, Operand(kPointerSize));
- __ IncrementCounter(COUNTERS->constructed_objects(), 1, r1, r2);
- __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1, r1, r2);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->constructed_objects(), 1, r1, r2);
+ __ IncrementCounter(counters->constructed_objects_stub(), 1, r1, r2);
__ Jump(lr);
// Jump to the generic stub in case the specialized code cannot handle the
// construction.
__ bind(&generic_stub_call);
- Code* code = Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructStubGeneric);
- Handle<Code> generic_construct_stub(code);
- __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
+ Handle<Code> code = masm()->isolate()->builtins()->JSConstructStubGeneric();
+ __ Jump(code, RelocInfo::CODE_TARGET);
// Return the generated code.
return GetCode();
@@ -3502,7 +3510,7 @@
__ ldr(value, MemOperand(r3, key, LSL, 1));
break;
case kExternalFloatArray:
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
__ add(r2, r3, Operand(key, LSL, 1));
__ vldr(s0, r2, 0);
@@ -3541,7 +3549,7 @@
// Now we can use r0 for the result as key is not needed any more.
__ mov(r0, r5);
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
__ vmov(s0, value);
__ vcvt_f64_s32(d0, s0);
@@ -3556,7 +3564,7 @@
// The test is different for unsigned int values. Since we need
// the value to be in the range of a positive smi, we can't
// handle either of the top two bits being set in the value.
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
Label box_int, done;
__ tst(value, Operand(0xC0000000));
@@ -3620,7 +3628,7 @@
} else if (array_type == kExternalFloatArray) {
// For the floating-point array type, we need to always allocate a
// HeapNumber.
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
// Allocate a HeapNumber for the result. Don't use r0 and r1 as
// AllocateHeapNumber clobbers all registers - also when jumping due to
@@ -3696,7 +3704,9 @@
// Slow case, key and receiver still in r0 and r1.
__ bind(&slow);
- __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1, r2, r3);
+ __ IncrementCounter(
+ masm()->isolate()->counters()->keyed_load_external_array_slow(),
+ 1, r2, r3);
// ---------- S t a t e --------------
// -- lr : return address
@@ -3811,10 +3821,9 @@
// The WebGL specification leaves the behavior of storing NaN and
// +/-Infinity into integer arrays basically undefined. For more
// reproducible behavior, convert these to zero.
- if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+ if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
-
if (array_type == kExternalFloatArray) {
// vldr requires offset to be a multiple of 4 so we can not
// include -kHeapObjectTag into it.
diff --git a/src/arm/virtual-frame-arm.cc b/src/arm/virtual-frame-arm.cc
index c4919b8..a852d6e 100644
--- a/src/arm/virtual-frame-arm.cc
+++ b/src/arm/virtual-frame-arm.cc
@@ -322,7 +322,7 @@
void VirtualFrame::CallLoadIC(Handle<String> name, RelocInfo::Mode mode) {
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Builtins::kLoadIC_Initialize));
PopToR0();
SpillAll();
__ mov(r2, Operand(name));
@@ -334,8 +334,8 @@
bool is_contextual,
StrictModeFlag strict_mode) {
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ (strict_mode == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+ : Builtins::kStoreIC_Initialize));
PopToR0();
RelocInfo::Mode mode;
if (is_contextual) {
@@ -354,7 +354,7 @@
void VirtualFrame::CallKeyedLoadIC() {
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Builtins::kKeyedLoadIC_Initialize));
PopToR1R0();
SpillAll();
CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
@@ -363,8 +363,8 @@
void VirtualFrame::CallKeyedStoreIC(StrictModeFlag strict_mode) {
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ (strict_mode == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+ : Builtins::kKeyedStoreIC_Initialize));
PopToR1R0();
SpillAll();
EmitPop(r2);
@@ -388,7 +388,7 @@
break;
case Code::BUILTIN:
ASSERT(*code == Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Builtins::kJSConstructCall));
break;
default:
UNREACHABLE();
diff --git a/src/assembler.cc b/src/assembler.cc
index c6d1cfa..58ec8ca 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -140,6 +140,7 @@
const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;
const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;
+const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask;
const int kVariableLengthPCJumpTopTag = 1;
const int kChunkBits = 7;
@@ -217,7 +218,6 @@
#ifdef DEBUG
byte* begin_pos = pos_;
#endif
- COUNTERS->reloc_info_count()->Increment();
ASSERT(rinfo->pc() - last_pc_ >= 0);
ASSERT(RelocInfo::NUMBER_OF_MODES <= kMaxRelocModes);
// Use unsigned delta-encoding for pc.
diff --git a/src/assembler.h b/src/assembler.h
index 8147227..62fe04d 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -205,6 +205,9 @@
// The maximum size for a call instruction including pc-jump.
static const int kMaxCallSize = 6;
+ // The maximum pc delta that will use the short encoding.
+ static const int kMaxSmallPCDelta;
+
enum Mode {
// Please note the order is important (see IsCodeTarget, IsGCRelocMode).
CONSTRUCT_CALL, // code target that is a call to a JavaScript constructor.
diff --git a/src/ast.cc b/src/ast.cc
index 3912773..8434357 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -527,12 +527,12 @@
// Record type feedback from the oracle in the AST.
is_monomorphic_ = oracle->LoadIsMonomorphic(this);
if (key()->IsPropertyName()) {
- if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_ArrayLength)) {
+ if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
is_array_length_ = true;
- } else if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_StringLength)) {
+ } else if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_StringLength)) {
is_string_length_ = true;
} else if (oracle->LoadIsBuiltin(this,
- Builtins::LoadIC_FunctionPrototype)) {
+ Builtins::kLoadIC_FunctionPrototype)) {
is_function_prototype_ = true;
} else {
Literal* lit_key = key()->AsLiteral();
@@ -541,7 +541,7 @@
ZoneMapList* types = oracle->LoadReceiverTypes(this, name);
receiver_types_ = types;
}
- } else if (oracle->LoadIsBuiltin(this, Builtins::KeyedLoadIC_String)) {
+ } else if (oracle->LoadIsBuiltin(this, Builtins::kKeyedLoadIC_String)) {
is_string_access_ = true;
} else if (is_monomorphic_) {
monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this);
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 015e702..e7c0554 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -445,7 +445,7 @@
// --- E m p t y ---
Handle<Code> code =
Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::EmptyFunction));
+ Builtins::kEmptyFunction));
empty_function->set_code(*code);
empty_function->shared()->set_code(*code);
Handle<String> source = FACTORY->NewStringFromAscii(CStrVector("() {}"));
@@ -587,9 +587,9 @@
// Create the ThrowTypeError function instances.
Handle<JSFunction> arguments_throw =
- CreateThrowTypeErrorFunction(Builtins::StrictFunctionArguments);
+ CreateThrowTypeErrorFunction(Builtins::kStrictFunctionArguments);
Handle<JSFunction> caller_throw =
- CreateThrowTypeErrorFunction(Builtins::StrictFunctionCaller);
+ CreateThrowTypeErrorFunction(Builtins::kStrictFunctionCaller);
// Complete the callback fixed arrays.
arguments->set(0, *arguments_throw);
@@ -673,7 +673,7 @@
if (js_global_template.is_null()) {
Handle<String> name = Handle<String>(HEAP->empty_symbol());
Handle<Code> code = Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::Illegal));
+ Builtins::kIllegal));
js_global_function =
FACTORY->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
JSGlobalObject::kSize, code, true);
@@ -707,7 +707,7 @@
if (global_template.IsEmpty()) {
Handle<String> name = Handle<String>(HEAP->empty_symbol());
Handle<Code> code = Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::Illegal));
+ Builtins::kIllegal));
global_proxy_function =
FACTORY->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
JSGlobalProxy::kSize, code, true);
@@ -796,15 +796,15 @@
// Install global Function object
InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
- empty_function, Builtins::Illegal, true); // ECMA native.
+ empty_function, Builtins::kIllegal, true); // ECMA native.
{ // --- A r r a y ---
Handle<JSFunction> array_function =
InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Isolate::Current()->initial_object_prototype(),
- Builtins::ArrayCode, true);
+ Builtins::kArrayCode, true);
array_function->shared()->set_construct_stub(
- Isolate::Current()->builtins()->builtin(Builtins::ArrayConstructCode));
+ Isolate::Current()->builtins()->builtin(Builtins::kArrayConstructCode));
array_function->shared()->DontAdaptArguments();
// This seems a bit hackish, but we need to make sure Array.length
@@ -832,7 +832,7 @@
Handle<JSFunction> number_fun =
InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
Isolate::Current()->initial_object_prototype(),
- Builtins::Illegal, true);
+ Builtins::kIllegal, true);
global_context()->set_number_function(*number_fun);
}
@@ -840,7 +840,7 @@
Handle<JSFunction> boolean_fun =
InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Isolate::Current()->initial_object_prototype(),
- Builtins::Illegal, true);
+ Builtins::kIllegal, true);
global_context()->set_boolean_function(*boolean_fun);
}
@@ -848,9 +848,10 @@
Handle<JSFunction> string_fun =
InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
Isolate::Current()->initial_object_prototype(),
- Builtins::Illegal, true);
+ Builtins::kIllegal, true);
string_fun->shared()->set_construct_stub(
- Isolate::Current()->builtins()->builtin(Builtins::StringConstructCode));
+ Isolate::Current()->builtins()->builtin(
+ Builtins::kStringConstructCode));
global_context()->set_string_function(*string_fun);
// Add 'length' property to strings.
Handle<DescriptorArray> string_descriptors =
@@ -872,7 +873,7 @@
Handle<JSFunction> date_fun =
InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
Isolate::Current()->initial_object_prototype(),
- Builtins::Illegal, true);
+ Builtins::kIllegal, true);
global_context()->set_date_function(*date_fun);
}
@@ -883,7 +884,7 @@
Handle<JSFunction> regexp_fun =
InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Isolate::Current()->initial_object_prototype(),
- Builtins::Illegal, true);
+ Builtins::kIllegal, true);
global_context()->set_regexp_function(*regexp_fun);
ASSERT(regexp_fun->has_initial_map());
@@ -968,7 +969,7 @@
// class_name equals 'Arguments'.
Handle<String> symbol = FACTORY->LookupAsciiSymbol("Arguments");
Handle<Code> code = Handle<Code>(
- Isolate::Current()->builtins()->builtin(Builtins::Illegal));
+ Isolate::Current()->builtins()->builtin(Builtins::kIllegal));
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(global_context()->object_function()->prototype()));
@@ -1023,9 +1024,9 @@
Handle<FixedArray> caller = FACTORY->NewFixedArray(2, TENURED);
Handle<JSFunction> callee_throw =
- CreateThrowTypeErrorFunction(Builtins::StrictArgumentsCallee);
+ CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCallee);
Handle<JSFunction> caller_throw =
- CreateThrowTypeErrorFunction(Builtins::StrictArgumentsCaller);
+ CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCaller);
// Install the ThrowTypeError functions.
callee->set(0, *callee_throw);
@@ -1088,7 +1089,7 @@
{ // --- context extension
// Create a function for the context extension objects.
Handle<Code> code = Handle<Code>(
- Isolate::Current()->builtins()->builtin(Builtins::Illegal));
+ Isolate::Current()->builtins()->builtin(Builtins::kIllegal));
Handle<JSFunction> context_extension_fun =
FACTORY->NewFunction(FACTORY->empty_symbol(),
JS_CONTEXT_EXTENSION_OBJECT_TYPE,
@@ -1106,7 +1107,7 @@
// Setup the call-as-function delegate.
Handle<Code> code =
Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::HandleApiCallAsFunction));
+ Builtins::kHandleApiCallAsFunction));
Handle<JSFunction> delegate =
FACTORY->NewFunction(FACTORY->empty_symbol(), JS_OBJECT_TYPE,
JSObject::kHeaderSize, code, true);
@@ -1118,7 +1119,7 @@
// Setup the call-as-constructor delegate.
Handle<Code> code =
Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::HandleApiCallAsConstructor));
+ Builtins::kHandleApiCallAsConstructor));
Handle<JSFunction> delegate =
FACTORY->NewFunction(FACTORY->empty_symbol(), JS_OBJECT_TYPE,
JSObject::kHeaderSize, code, true);
@@ -1251,7 +1252,7 @@
// JavaScript builtins, a reference to the builtins object
// (itself) and a reference to the global_context directly in the object.
Handle<Code> code = Handle<Code>(
- isolate->builtins()->builtin(Builtins::Illegal));
+ isolate->builtins()->builtin(Builtins::kIllegal));
Handle<JSFunction> builtins_fun =
factory->NewFunction(factory->empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
JSBuiltinsObject::kSize, code, true);
@@ -1296,7 +1297,7 @@
Handle<JSFunction> script_fun =
InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
isolate->initial_object_prototype(),
- Builtins::Illegal, false);
+ Builtins::kIllegal, false);
Handle<JSObject> prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
SetPrototype(script_fun, prototype);
@@ -1421,7 +1422,7 @@
InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
JSValue::kSize,
isolate->initial_object_prototype(),
- Builtins::Illegal, false);
+ Builtins::kIllegal, false);
Handle<JSObject> prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
SetPrototype(opaque_reference_fun, prototype);
@@ -1443,14 +1444,14 @@
JS_ARRAY_TYPE,
JSArray::kSize,
isolate->initial_object_prototype(),
- Builtins::ArrayCode,
+ Builtins::kArrayCode,
true);
Handle<JSObject> prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
SetPrototype(array_function, prototype);
array_function->shared()->set_construct_stub(
- isolate->builtins()->builtin(Builtins::ArrayConstructCode));
+ isolate->builtins()->builtin(Builtins::kArrayConstructCode));
array_function->shared()->DontAdaptArguments();
// Make "length" magic on instances.
@@ -1505,12 +1506,12 @@
Handle<JSFunction> call =
InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Handle<JSObject>::null(),
- Builtins::FunctionCall,
+ Builtins::kFunctionCall,
false);
Handle<JSFunction> apply =
InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Handle<JSObject>::null(),
- Builtins::FunctionApply,
+ Builtins::kFunctionApply,
false);
// Make sure that Function.prototype.call appears to be compiled.
@@ -1936,6 +1937,7 @@
break;
}
case MAP_TRANSITION:
+ case EXTERNAL_ARRAY_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
// Ignore non-properties.
diff --git a/src/builtins.cc b/src/builtins.cc
index 4604872..72f9d57 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1576,7 +1576,7 @@
functions->generator = FUNCTION_ADDR(Generate_##aname); \
functions->c_code = NULL; \
functions->s_name = #aname; \
- functions->name = aname; \
+ functions->name = k##aname; \
functions->flags = Code::ComputeFlags(Code::kind, \
NOT_IN_LOOP, \
state, \
@@ -1685,4 +1685,23 @@
}
+#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \
+Handle<Code> Builtins::name() { \
+ Code** code_address = \
+ reinterpret_cast<Code**>(builtin_address(k##name)); \
+ return Handle<Code>(code_address); \
+}
+#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
+Handle<Code> Builtins::name() { \
+ Code** code_address = \
+ reinterpret_cast<Code**>(builtin_address(k##name)); \
+ return Handle<Code>(code_address); \
+}
+BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
+BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
+BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
+#undef DEFINE_BUILTIN_ACCESSOR_C
+#undef DEFINE_BUILTIN_ACCESSOR_A
+
+
} } // namespace v8::internal
diff --git a/src/builtins.h b/src/builtins.h
index 4dd6111..bc0facb 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -260,8 +260,8 @@
const char* Lookup(byte* pc);
enum Name {
-#define DEF_ENUM_C(name, ignore) name,
-#define DEF_ENUM_A(name, kind, state, extra) name,
+#define DEF_ENUM_C(name, ignore) k##name,
+#define DEF_ENUM_A(name, kind, state, extra) k##name,
BUILTIN_LIST_C(DEF_ENUM_C)
BUILTIN_LIST_A(DEF_ENUM_A)
BUILTIN_LIST_DEBUG_A(DEF_ENUM_A)
@@ -284,6 +284,15 @@
id_count
};
+#define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name();
+#define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
+ Handle<Code> name();
+ BUILTIN_LIST_C(DECLARE_BUILTIN_ACCESSOR_C)
+ BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A)
+ BUILTIN_LIST_DEBUG_A(DECLARE_BUILTIN_ACCESSOR_A)
+#undef DECLARE_BUILTIN_ACCESSOR_C
+#undef DECLARE_BUILTIN_ACCESSOR_A
+
Code* builtin(Name name) {
// Code::cast cannot be used here since we access builtins
// during the marking phase of mark sweep. See IC::Clear.
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index cfe9309..b370c65 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -48,7 +48,7 @@
void CodeStub::GenerateCode(MacroAssembler* masm) {
// Update the static counter each time a new code stub is generated.
- COUNTERS->code_stubs()->Increment();
+ masm->isolate()->counters()->code_stubs()->Increment();
// Nested stubs are not allowed for leafs.
AllowStubCallsScope allow_scope(masm, AllowsStubCalls());
@@ -62,9 +62,11 @@
void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
code->set_major_key(MajorKey());
- PROFILE(ISOLATE, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
+ Isolate* isolate = masm->isolate();
+ PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
- COUNTERS->total_stubs_code_size()->Increment(code->instruction_size());
+ Counters* counters = isolate->counters();
+ counters->total_stubs_code_size()->Increment(code->instruction_size());
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_code_stubs) {
diff --git a/src/codegen.cc b/src/codegen.cc
index 5a99272..03f64a1 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -175,13 +175,17 @@
Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
Code::Flags flags,
CompilationInfo* info) {
+ Isolate* isolate = info->isolate();
+
// Allocate and install the code.
CodeDesc desc;
masm->GetCode(&desc);
- Handle<Code> code = FACTORY->NewCode(desc, flags, masm->CodeObject());
+ Handle<Code> code =
+ isolate->factory()->NewCode(desc, flags, masm->CodeObject());
if (!code.is_null()) {
- COUNTERS->total_compiled_code_size()->Increment(code->instruction_size());
+ isolate->counters()->total_compiled_code_size()->Increment(
+ code->instruction_size());
}
return code;
}
@@ -235,7 +239,8 @@
Handle<Script> script = info->script();
if (!script->IsUndefined() && !script->source()->IsUndefined()) {
int len = String::cast(script->source())->length();
- COUNTERS->total_old_codegen_source_size()->Increment(len);
+ Counters* counters = info->isolate()->counters();
+ counters->total_old_codegen_source_size()->Increment(len);
}
if (FLAG_trace_codegen) {
PrintF("Classic Compiler - ");
diff --git a/src/compiler.cc b/src/compiler.cc
index 85448dd..1ec4414 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -203,6 +203,10 @@
Handle<Code> code(info->shared_info()->code());
ASSERT(code->kind() == Code::FUNCTION);
+ // We should never arrive here if optimization has been disabled on the
+ // shared function info.
+ ASSERT(!info->shared_info()->optimization_disabled());
+
// Fall back to using the full code generator if it's not possible
// to use the Hydrogen-based optimizing compiler. We already have
// generated code for this from the shared function object.
@@ -409,8 +413,8 @@
// rest of the function into account to avoid overlap with the
// parsing statistics.
HistogramTimer* rate = info->is_eval()
- ? COUNTERS->compile_eval()
- : COUNTERS->compile();
+ ? info->isolate()->counters()->compile_eval()
+ : info->isolate()->counters()->compile();
HistogramTimerScope timer(rate);
// Compile the code.
@@ -480,10 +484,10 @@
ScriptDataImpl* input_pre_data,
Handle<Object> script_data,
NativesFlag natives) {
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = source->GetIsolate();
int source_length = source->length();
- COUNTERS->total_load_size()->Increment(source_length);
- COUNTERS->total_compile_size()->Increment(source_length);
+ isolate->counters()->total_load_size()->Increment(source_length);
+ isolate->counters()->total_compile_size()->Increment(source_length);
// The VM is in the COMPILER state until exiting this function.
VMState state(isolate, COMPILER);
@@ -629,6 +633,11 @@
} else {
ASSERT(!info->code().is_null());
Handle<Code> code = info->code();
+ // Set optimizable to false if this is disallowed by the shared
+ // function info, e.g., we might have flushed the code and must
+ // reset this bit when lazy compiling the code again.
+ if (shared->optimization_disabled()) code->set_optimizable(false);
+
Handle<JSFunction> function = info->closure();
RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
@@ -665,7 +674,7 @@
ASSERT(shared->is_compiled());
shared->set_code_age(0);
- if (V8::UseCrankshaft() && info->AllowOptimize()) {
+ if (info->AllowOptimize() && !shared->optimization_disabled()) {
// If we're asked to always optimize, we compile the optimized
// version of the function right away - unless the debugger is
// active as it makes no sense to compile optimized code then.
@@ -710,8 +719,7 @@
// Generate code
if (FLAG_lazy && allow_lazy) {
- Handle<Code> code(
- info.isolate()->builtins()->builtin(Builtins::LazyCompile));
+ Handle<Code> code = info.isolate()->builtins()->LazyCompile();
info.SetCode(code);
} else {
if (V8::UseCrankshaft()) {
@@ -801,7 +809,7 @@
if (info->isolate()->logger()->is_logging() || CpuProfiler::is_profiling()) {
Handle<Script> script = info->script();
Handle<Code> code = info->code();
- if (*code == info->isolate()->builtins()->builtin(Builtins::LazyCompile))
+ if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile))
return;
if (script->name()->IsString()) {
int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
diff --git a/src/debug.cc b/src/debug.cc
index 10b8b4a..87afe34 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -717,11 +717,11 @@
if (create_heap_objects) {
// Get code to handle debug break on return.
debug_break_return_ =
- Isolate::Current()->builtins()->builtin(Builtins::Return_DebugBreak);
+ Isolate::Current()->builtins()->builtin(Builtins::kReturn_DebugBreak);
ASSERT(debug_break_return_->IsCode());
// Get code to handle debug break in debug break slots.
debug_break_slot_ =
- Isolate::Current()->builtins()->builtin(Builtins::Slot_DebugBreak);
+ Isolate::Current()->builtins()->builtin(Builtins::kSlot_DebugBreak);
ASSERT(debug_break_slot_->IsCode());
}
}
@@ -1007,14 +1007,15 @@
FRAME_DROPPED_IN_IC_CALL) {
// We must have been calling IC stub. Do not go there anymore.
Code* plain_return =
- Isolate::Current()->builtins()->builtin(Builtins::PlainReturn_LiveEdit);
+ Isolate::Current()->builtins()->builtin(
+ Builtins::kPlainReturn_LiveEdit);
debug->thread_local_.after_break_target_ = plain_return->entry();
} else if (debug->thread_local_.frame_drop_mode_ ==
FRAME_DROPPED_IN_DEBUG_SLOT_CALL) {
// Debug break slot stub does not return normally, instead it manually
// cleans the stack and jumps. We should patch the jump address.
Code* plain_return = Isolate::Current()->builtins()->builtin(
- Builtins::FrameDropper_LiveEdit);
+ Builtins::kFrameDropper_LiveEdit);
debug->thread_local_.after_break_target_ = plain_return->entry();
} else if (debug->thread_local_.frame_drop_mode_ ==
FRAME_DROPPED_IN_DIRECT_CALL) {
@@ -1517,22 +1518,16 @@
return ComputeCallDebugBreak(code->arguments_count(), code->kind());
case Code::LOAD_IC:
- return Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_DebugBreak));
+ return Isolate::Current()->builtins()->LoadIC_DebugBreak();
case Code::STORE_IC:
- return Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_DebugBreak));
+ return Isolate::Current()->builtins()->StoreIC_DebugBreak();
case Code::KEYED_LOAD_IC:
- return Handle<Code>(
- Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_DebugBreak));
+ return Isolate::Current()->builtins()->KeyedLoadIC_DebugBreak();
case Code::KEYED_STORE_IC:
- return Handle<Code>(
- Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_DebugBreak));
+ return Isolate::Current()->builtins()->KeyedStoreIC_DebugBreak();
default:
UNREACHABLE();
@@ -1540,15 +1535,13 @@
}
if (RelocInfo::IsConstructCall(mode)) {
Handle<Code> result =
- Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::ConstructCall_DebugBreak));
+ Isolate::Current()->builtins()->ConstructCall_DebugBreak();
return result;
}
if (code->kind() == Code::STUB) {
ASSERT(code->major_key() == CodeStub::CallFunction);
Handle<Code> result =
- Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::StubNoRegisters_DebugBreak));
+ Isolate::Current()->builtins()->StubNoRegisters_DebugBreak();
return result;
}
@@ -1616,9 +1609,9 @@
// Don't allow step into functions in the native context.
if (!function->IsBuiltin()) {
if (function->shared()->code() ==
- Isolate::Current()->builtins()->builtin(Builtins::FunctionApply) ||
+ Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) ||
function->shared()->code() ==
- Isolate::Current()->builtins()->builtin(Builtins::FunctionCall)) {
+ Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) {
// Handle function.apply and function.call separately to flood the
// function to be called and not the code for Builtins::FunctionApply or
// Builtins::FunctionCall. The receiver of call/apply is the target
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index ef27646..a53de3d 100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -136,6 +136,13 @@
Isolate* isolate);
static Deoptimizer* Grab(Isolate* isolate);
+ // Makes sure that there is enough room in the relocation
+ // information of a code object to perform lazy deoptimization
+ // patching. If there is not enough room a new relocation
+ // information object is allocated and comments are added until it
+ // is big enough.
+ static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code);
+
// Deoptimize the function now. Its current optimized code will never be run
// again and any activations of the optimized code will get deoptimized when
// execution returns.
@@ -319,7 +326,9 @@
JSFunction* function);
void* operator new(size_t size, uint32_t frame_size) {
- return malloc(size + frame_size);
+ // Subtracts kPointerSize, as the member frame_content_ already supplies
+ // the first element of the area to store the frame.
+ return malloc(size + frame_size - kPointerSize);
}
void operator delete(void* description) {
@@ -403,7 +412,7 @@
}
static int frame_content_offset() {
- return sizeof(FrameDescription);
+ return OFFSET_OF(FrameDescription, frame_content_);
}
private:
@@ -422,6 +431,10 @@
// deoptimizing.
intptr_t continuation_;
+ // This must be at the end of the object as the object is allocated larger
+ // than it's definition indicate to extend this array.
+ intptr_t frame_content_[1];
+
intptr_t* GetFrameSlotPointer(unsigned offset) {
ASSERT(offset < frame_size_);
return reinterpret_cast<intptr_t*>(
diff --git a/src/factory.cc b/src/factory.cc
index d798c3e..7dee66f 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -392,8 +392,14 @@
}
-Handle<Map> Factory::NewExternalArrayElementsMap(Handle<Map> src) {
- CALL_HEAP_FUNCTION(isolate(), src->NewExternalArrayElementsMap(), Map);
+Handle<Map> Factory::GetExternalArrayElementsMap(
+ Handle<Map> src,
+ ExternalArrayType array_type,
+ bool safe_to_add_transition) {
+ CALL_HEAP_FUNCTION(isolate(),
+ src->GetExternalArrayElementsMap(array_type,
+ safe_to_add_transition),
+ Map);
}
@@ -987,11 +993,8 @@
Handle<JSFunction> Factory::CreateApiFunction(
Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) {
- Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
- Builtins::HandleApiCall));
- Handle<Code> construct_stub =
- Handle<Code>(isolate()->builtins()->builtin(
- Builtins::JSConstructStubApi));
+ Handle<Code> code = isolate()->builtins()->HandleApiCall();
+ Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();
int internal_field_count = 0;
if (!obj->instance_template()->IsUndefined()) {
diff --git a/src/factory.h b/src/factory.h
index d9d5ec4..71bfdc4 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -192,7 +192,9 @@
Handle<Map> GetSlowElementsMap(Handle<Map> map);
- Handle<Map> NewExternalArrayElementsMap(Handle<Map> map);
+ Handle<Map> GetExternalArrayElementsMap(Handle<Map> map,
+ ExternalArrayType array_type,
+ bool safe_to_add_transition);
Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
diff --git a/src/frames.cc b/src/frames.cc
index 30d0456..79aa250 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -851,7 +851,7 @@
Code* ArgumentsAdaptorFrame::unchecked_code() const {
return Isolate::Current()->builtins()->builtin(
- Builtins::ArgumentsAdaptorTrampoline);
+ Builtins::kArgumentsAdaptorTrampoline);
}
@@ -1147,14 +1147,14 @@
PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) {
- COUNTERS->pc_to_code()->Increment();
+ isolate_->counters()->pc_to_code()->Increment();
ASSERT(IsPowerOf2(kPcToCodeCacheSize));
uint32_t hash = ComputeIntegerHash(
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pc)));
uint32_t index = hash & (kPcToCodeCacheSize - 1);
PcToCodeCacheEntry* entry = cache(index);
if (entry->pc == pc) {
- COUNTERS->pc_to_code_cached()->Increment();
+ isolate_->counters()->pc_to_code_cached()->Increment();
ASSERT(entry->code == GcSafeFindCodeForPc(pc));
} else {
// Because this code may be interrupted by a profiling signal that
diff --git a/src/heap.cc b/src/heap.cc
index 9a5a2b0..1c1e084 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2271,11 +2271,11 @@
SharedFunctionInfo* share = SharedFunctionInfo::cast(result);
share->set_name(name);
- Code* illegal = isolate_->builtins()->builtin(Builtins::Illegal);
+ Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
share->set_code(illegal);
share->set_scope_info(SerializedScopeInfo::Empty());
Code* construct_stub = isolate_->builtins()->builtin(
- Builtins::JSConstructStubGeneric);
+ Builtins::kJSConstructStubGeneric);
share->set_construct_stub(construct_stub);
share->set_expected_nof_properties(0);
share->set_length(0);
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index e253795..c73ce4c 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1156,6 +1156,60 @@
}
+HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* object,
+ ZoneMapList* types,
+ Handle<String> name)
+ : HUnaryOperation(object),
+ types_(Min(types->length(), kMaxLoadPolymorphism)),
+ name_(name),
+ need_generic_(false) {
+ set_representation(Representation::Tagged());
+ SetFlag(kDependsOnMaps);
+ for (int i = 0;
+ i < types->length() && types_.length() < kMaxLoadPolymorphism;
+ ++i) {
+ Handle<Map> map = types->at(i);
+ LookupResult lookup;
+ map->LookupInDescriptors(NULL, *name, &lookup);
+ if (lookup.IsProperty() && lookup.type() == FIELD) {
+ types_.Add(types->at(i));
+ int index = lookup.GetLocalFieldIndexFromMap(*map);
+ if (index < 0) {
+ SetFlag(kDependsOnInobjectFields);
+ } else {
+ SetFlag(kDependsOnBackingStoreFields);
+ }
+ }
+ }
+
+ if (types_.length() == types->length() && FLAG_deoptimize_uncommon_cases) {
+ SetFlag(kUseGVN);
+ } else {
+ SetAllSideEffects();
+ need_generic_ = true;
+ }
+}
+
+
+bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) {
+ HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value);
+ if (types_.length() != other->types()->length()) return false;
+ if (!name_.is_identical_to(other->name())) return false;
+ if (need_generic_ != other->need_generic_) return false;
+ for (int i = 0; i < types_.length(); i++) {
+ bool found = false;
+ for (int j = 0; j < types_.length(); j++) {
+ if (types_.at(j).is_identical_to(other->types()->at(i))) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) return false;
+ }
+ return true;
+}
+
+
void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
stream->Add("[");
@@ -1172,8 +1226,36 @@
}
-void HLoadPixelArrayElement::PrintDataTo(StringStream* stream) {
+void HLoadKeyedSpecializedArrayElement::PrintDataTo(
+ StringStream* stream) {
external_pointer()->PrintNameTo(stream);
+ stream->Add(".");
+ switch (array_type()) {
+ case kExternalByteArray:
+ stream->Add("byte");
+ break;
+ case kExternalUnsignedByteArray:
+ stream->Add("u_byte");
+ break;
+ case kExternalShortArray:
+ stream->Add("short");
+ break;
+ case kExternalUnsignedShortArray:
+ stream->Add("u_short");
+ break;
+ case kExternalIntArray:
+ stream->Add("int");
+ break;
+ case kExternalUnsignedIntArray:
+ stream->Add("u_int");
+ break;
+ case kExternalFloatArray:
+ stream->Add("float");
+ break;
+ case kExternalPixelArray:
+ stream->Add("pixel");
+ break;
+ }
stream->Add("[");
key()->PrintNameTo(stream);
stream->Add("]");
@@ -1221,8 +1303,36 @@
}
-void HStorePixelArrayElement::PrintDataTo(StringStream* stream) {
+void HStoreKeyedSpecializedArrayElement::PrintDataTo(
+ StringStream* stream) {
external_pointer()->PrintNameTo(stream);
+ stream->Add(".");
+ switch (array_type()) {
+ case kExternalByteArray:
+ stream->Add("byte");
+ break;
+ case kExternalUnsignedByteArray:
+ stream->Add("u_byte");
+ break;
+ case kExternalShortArray:
+ stream->Add("short");
+ break;
+ case kExternalUnsignedShortArray:
+ stream->Add("u_short");
+ break;
+ case kExternalIntArray:
+ stream->Add("int");
+ break;
+ case kExternalUnsignedIntArray:
+ stream->Add("u_int");
+ break;
+ case kExternalFloatArray:
+ stream->Add("float");
+ break;
+ case kExternalPixelArray:
+ stream->Add("pixel");
+ break;
+ }
stream->Add("[");
key()->PrintNameTo(stream);
stream->Add("] = ");
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 3ca76f7..fed4b8b 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -29,7 +29,9 @@
#define V8_HYDROGEN_INSTRUCTIONS_H_
#include "v8.h"
+
#include "code-stubs.h"
+#include "small-pointer-list.h"
#include "string-stream.h"
#include "zone.h"
@@ -125,9 +127,10 @@
V(LoadGlobal) \
V(LoadKeyedFastElement) \
V(LoadKeyedGeneric) \
+ V(LoadKeyedSpecializedArrayElement) \
V(LoadNamedField) \
+ V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
- V(LoadPixelArrayElement) \
V(Mod) \
V(Mul) \
V(ObjectLiteral) \
@@ -146,7 +149,7 @@
V(StoreContextSlot) \
V(StoreGlobal) \
V(StoreKeyedFastElement) \
- V(StorePixelArrayElement) \
+ V(StoreKeyedSpecializedArrayElement) \
V(StoreKeyedGeneric) \
V(StoreNamedField) \
V(StoreNamedGeneric) \
@@ -168,7 +171,7 @@
V(InobjectFields) \
V(BackingStoreFields) \
V(ArrayElements) \
- V(PixelArrayElements) \
+ V(SpecializedArrayElements) \
V(GlobalVars) \
V(Maps) \
V(ArrayLengths) \
@@ -451,7 +454,6 @@
HValue() : block_(NULL),
id_(kNoNumber),
- uses_(2),
type_(HType::Tagged()),
range_(NULL),
flags_(0) {}
@@ -463,7 +465,7 @@
int id() const { return id_; }
void set_id(int id) { id_ = id; }
- ZoneList<HValue*>* uses() { return &uses_; }
+ SmallPointerList<HValue>* uses() { return &uses_; }
virtual bool EmitAtUses() { return false; }
Representation representation() const { return representation_; }
@@ -607,7 +609,7 @@
int id_;
Representation representation_;
- ZoneList<HValue*> uses_;
+ SmallPointerList<HValue> uses_;
HType type_;
Range* range_;
int flags_;
@@ -1246,7 +1248,7 @@
bool IsApplyFunction() const {
return function_->code() ==
- Isolate::Current()->builtins()->builtin(Builtins::FunctionApply);
+ Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
}
virtual void PrintDataTo(StringStream* stream);
@@ -1406,8 +1408,9 @@
// object. It is guaranteed to be 32 bit integer, but it can be
// represented as either a smi or heap number.
set_representation(Representation::Tagged());
- SetFlag(kDependsOnArrayLengths);
SetFlag(kUseGVN);
+ SetFlag(kDependsOnArrayLengths);
+ SetFlag(kDependsOnMaps);
}
virtual Representation RequiredInputRepresentation(int index) const {
@@ -1425,8 +1428,8 @@
public:
explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
set_representation(Representation::Tagged());
- SetFlag(kDependsOnArrayLengths);
SetFlag(kUseGVN);
+ SetFlag(kDependsOnArrayLengths);
}
virtual Representation RequiredInputRepresentation(int index) const {
@@ -1584,7 +1587,7 @@
: HUnaryOperation(value) {
set_representation(Representation::External());
// The result of this instruction is idempotent as long as its inputs don't
- // change. The external array of a pixel array elements object cannot
+ // change. The external array of a specialized array elements object cannot
// change once set, so it's no necessary to introduce any additional
// dependencies on top of the inputs.
SetFlag(kUseGVN);
@@ -2256,6 +2259,7 @@
: HBinaryOperation(left, right) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
+ SetFlag(kDependsOnMaps);
}
virtual bool EmitAtUses() {
@@ -2941,6 +2945,7 @@
offset_(offset) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
+ SetFlag(kDependsOnMaps);
if (is_in_object) {
SetFlag(kDependsOnInobjectFields);
} else {
@@ -2971,6 +2976,37 @@
};
+class HLoadNamedFieldPolymorphic: public HUnaryOperation {
+ public:
+ HLoadNamedFieldPolymorphic(HValue* object,
+ ZoneMapList* types,
+ Handle<String> name);
+
+ HValue* object() { return OperandAt(0); }
+ ZoneMapList* types() { return &types_; }
+ Handle<String> name() { return name_; }
+ bool need_generic() { return need_generic_; }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic,
+ "load_named_field_polymorphic")
+
+ static const int kMaxLoadPolymorphism = 4;
+
+ protected:
+ virtual bool DataEquals(HValue* value);
+
+ private:
+ ZoneMapList types_;
+ Handle<String> name_;
+ bool need_generic_;
+};
+
+
+
class HLoadNamedGeneric: public HBinaryOperation {
public:
HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
@@ -3043,13 +3079,20 @@
};
-class HLoadPixelArrayElement: public HBinaryOperation {
+class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
public:
- HLoadPixelArrayElement(HValue* external_elements, HValue* key)
- : HBinaryOperation(external_elements, key) {
- set_representation(Representation::Integer32());
- SetFlag(kDependsOnPixelArrayElements);
- // Native code could change the pixel array.
+ HLoadKeyedSpecializedArrayElement(HValue* external_elements,
+ HValue* key,
+ ExternalArrayType array_type)
+ : HBinaryOperation(external_elements, key),
+ array_type_(array_type) {
+ if (array_type == kExternalFloatArray) {
+ set_representation(Representation::Double());
+ } else {
+ set_representation(Representation::Integer32());
+ }
+ SetFlag(kDependsOnSpecializedArrayElements);
+ // Native code could change the specialized array.
SetFlag(kDependsOnCalls);
SetFlag(kUseGVN);
}
@@ -3065,12 +3108,21 @@
HValue* external_pointer() { return OperandAt(0); }
HValue* key() { return OperandAt(1); }
+ ExternalArrayType array_type() const { return array_type_; }
- DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
- "load_pixel_array_element")
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+ "load_keyed_specialized_array_element")
protected:
- virtual bool DataEquals(HValue* other) { return true; }
+ virtual bool DataEquals(HValue* other) {
+ if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
+ HLoadKeyedSpecializedArrayElement* cast_other =
+ HLoadKeyedSpecializedArrayElement::cast(other);
+ return array_type_ == cast_other->array_type();
+ }
+
+ private:
+ ExternalArrayType array_type_;
};
@@ -3205,10 +3257,14 @@
};
-class HStorePixelArrayElement: public HTemplateInstruction<3> {
+class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
public:
- HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
- SetFlag(kChangesPixelArrayElements);
+ HStoreKeyedSpecializedArrayElement(HValue* external_elements,
+ HValue* key,
+ HValue* val,
+ ExternalArrayType array_type)
+ : array_type_(array_type) {
+ SetFlag(kChangesSpecializedArrayElements);
SetOperandAt(0, external_elements);
SetOperandAt(1, key);
SetOperandAt(2, val);
@@ -3220,16 +3276,23 @@
if (index == 0) {
return Representation::External();
} else {
- return Representation::Integer32();
+ if (index == 2 && array_type() == kExternalFloatArray) {
+ return Representation::Double();
+ } else {
+ return Representation::Integer32();
+ }
}
}
HValue* external_pointer() { return OperandAt(0); }
HValue* key() { return OperandAt(1); }
HValue* value() { return OperandAt(2); }
+ ExternalArrayType array_type() const { return array_type_; }
- DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
- "store_pixel_array_element")
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+ "store_keyed_specialized_array_element")
+ private:
+ ExternalArrayType array_type_;
};
@@ -3267,6 +3330,7 @@
: HBinaryOperation(string, index) {
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
+ SetFlag(kDependsOnMaps);
}
virtual Representation RequiredInputRepresentation(int index) const {
@@ -3311,6 +3375,7 @@
explicit HStringLength(HValue* string) : HUnaryOperation(string) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
+ SetFlag(kDependsOnMaps);
}
virtual Representation RequiredInputRepresentation(int index) const {
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index e9bfafd..7d9c814 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -745,7 +745,7 @@
if (value != NULL) {
// Iterate through uses finding the ones that should be
// replaced.
- ZoneList<HValue*>* uses = phi->uses();
+ SmallPointerList<HValue>* uses = phi->uses();
while (!uses->is_empty()) {
HValue* use = uses->RemoveLast();
if (use != NULL) {
@@ -3219,9 +3219,10 @@
// never both. Pixel array maps that are assigned to pixel array elements
// are always created with the fast elements flag cleared.
if (receiver_type->has_external_array_elements()) {
- if (expr->GetExternalArrayType() == kExternalPixelArray) {
- instr = BuildStoreKeyedPixelArrayElement(object, key, value, expr);
- }
+ instr = BuildStoreKeyedSpecializedArrayElement(object,
+ key,
+ value,
+ expr);
} else if (receiver_type->has_fast_elements()) {
instr = BuildStoreKeyedFastElement(object, key, value, expr);
}
@@ -3445,69 +3446,6 @@
}
-void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
- HValue* object,
- ZoneMapList* types,
- Handle<String> name) {
- // TODO(ager): We should recognize when the prototype chains for different
- // maps are identical. In that case we can avoid repeatedly generating the
- // same prototype map checks.
- int count = 0;
- HBasicBlock* join = NULL;
- for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
- Handle<Map> map = types->at(i);
- LookupResult lookup;
- map->LookupInDescriptors(NULL, *name, &lookup);
- if (lookup.IsProperty() && lookup.type() == FIELD) {
- if (count == 0) {
- AddInstruction(new HCheckNonSmi(object)); // Only needed once.
- join = graph()->CreateBasicBlock();
- }
- ++count;
- HBasicBlock* if_true = graph()->CreateBasicBlock();
- HBasicBlock* if_false = graph()->CreateBasicBlock();
- HCompareMap* compare = new HCompareMap(object, map, if_true, if_false);
- current_block()->Finish(compare);
-
- set_current_block(if_true);
- HLoadNamedField* instr =
- BuildLoadNamedField(object, expr, map, &lookup, false);
- instr->set_position(expr->position());
- instr->ClearFlag(HValue::kUseGVN);
- AddInstruction(instr);
- if (!ast_context()->IsEffect()) Push(instr);
- current_block()->Goto(join);
-
- set_current_block(if_false);
- }
- }
-
- // Finish up. Unconditionally deoptimize if we've handled all the maps we
- // know about and do not want to handle ones we've never seen. Otherwise
- // use a generic IC.
- if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
- current_block()->FinishExitWithDeoptimization();
- } else {
- HInstruction* instr = BuildLoadNamedGeneric(object, expr);
- instr->set_position(expr->position());
-
- if (join != NULL) {
- AddInstruction(instr);
- if (!ast_context()->IsEffect()) Push(instr);
- current_block()->Goto(join);
- } else {
- ast_context()->ReturnInstruction(instr, expr->id());
- return;
- }
- }
-
- ASSERT(join != NULL);
- join->SetJoinId(expr->id());
- set_current_block(join);
- if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
-}
-
-
HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
Property* expr,
Handle<Map> type,
@@ -3597,9 +3535,10 @@
}
-HInstruction* HGraphBuilder::BuildLoadKeyedPixelArrayElement(HValue* object,
- HValue* key,
- Property* expr) {
+HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement(
+ HValue* object,
+ HValue* key,
+ Property* expr) {
ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
AddInstruction(new HCheckNonSmi(object));
Handle<Map> map = expr->GetMonomorphicReceiverType();
@@ -3614,8 +3553,10 @@
HLoadExternalArrayPointer* external_elements =
new HLoadExternalArrayPointer(elements);
AddInstruction(external_elements);
- HLoadPixelArrayElement* pixel_array_value =
- new HLoadPixelArrayElement(external_elements, key);
+ HLoadKeyedSpecializedArrayElement* pixel_array_value =
+ new HLoadKeyedSpecializedArrayElement(external_elements,
+ key,
+ expr->GetExternalArrayType());
return pixel_array_value;
}
@@ -3653,11 +3594,11 @@
}
-HInstruction* HGraphBuilder::BuildStoreKeyedPixelArrayElement(
+HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement(
HValue* object,
HValue* key,
HValue* val,
- Expression* expr) {
+ Assignment* expr) {
ASSERT(expr->IsMonomorphic());
AddInstruction(new HCheckNonSmi(object));
Handle<Map> map = expr->GetMonomorphicReceiverType();
@@ -3671,7 +3612,11 @@
HLoadExternalArrayPointer* external_elements =
new HLoadExternalArrayPointer(elements);
AddInstruction(external_elements);
- return new HStorePixelArrayElement(external_elements, key, val);
+ return new HStoreKeyedSpecializedArrayElement(
+ external_elements,
+ key,
+ val,
+ expr->GetExternalArrayType());
}
@@ -3748,9 +3693,8 @@
if (expr->IsMonomorphic()) {
instr = BuildLoadNamed(obj, expr, types->first(), name);
} else if (types != NULL && types->length() > 1) {
- HandlePolymorphicLoadNamedField(expr, obj, types, name);
- return;
-
+ AddInstruction(new HCheckNonSmi(obj));
+ instr = new HLoadNamedFieldPolymorphic(obj, types, name);
} else {
instr = BuildLoadNamedGeneric(obj, expr);
}
@@ -3767,9 +3711,7 @@
// both. Pixel array maps that are assigned to pixel array elements are
// always created with the fast elements flag cleared.
if (receiver_type->has_external_array_elements()) {
- if (expr->GetExternalArrayType() == kExternalPixelArray) {
- instr = BuildLoadKeyedPixelArrayElement(obj, key, expr);
- }
+ instr = BuildLoadKeyedSpecializedArrayElement(obj, key, expr);
} else if (receiver_type->has_fast_elements()) {
instr = BuildLoadKeyedFastElement(obj, key, expr);
}
@@ -5875,9 +5817,14 @@
PrintF(" %8u bytes / %4.1f %%\n", size, size_percent);
}
double source_size_in_kb = static_cast<double>(source_size_) / 1024;
+ double normalized_time = source_size_in_kb > 0
+ ? (static_cast<double>(sum) / 1000) / source_size_in_kb
+ : 0;
+ double normalized_bytes = source_size_in_kb > 0
+ ? total_size_ / source_size_in_kb
+ : 0;
PrintF("%30s - %7.3f ms %7.3f bytes\n", "Sum",
- (static_cast<double>(sum) / 1000) / source_size_in_kb,
- total_size_ / source_size_in_kb);
+ normalized_time, normalized_bytes);
PrintF("---------------------------------------------------------------\n");
PrintF("%30s - %7.3f ms (%.1f times slower than full code gen)\n",
"Total",
diff --git a/src/hydrogen.h b/src/hydrogen.h
index dee7866..e14799a 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -794,10 +794,6 @@
void HandlePropertyAssignment(Assignment* expr);
void HandleCompoundAssignment(Assignment* expr);
- void HandlePolymorphicLoadNamedField(Property* expr,
- HValue* object,
- ZoneMapList* types,
- Handle<String> name);
void HandlePolymorphicStoreNamedField(Assignment* expr,
HValue* object,
HValue* value,
@@ -823,9 +819,9 @@
HInstruction* BuildLoadKeyedFastElement(HValue* object,
HValue* key,
Property* expr);
- HInstruction* BuildLoadKeyedPixelArrayElement(HValue* object,
- HValue* key,
- Property* expr);
+ HInstruction* BuildLoadKeyedSpecializedArrayElement(HValue* object,
+ HValue* key,
+ Property* expr);
HInstruction* BuildLoadKeyedGeneric(HValue* object,
HValue* key);
@@ -854,10 +850,11 @@
HValue* val,
Expression* expr);
- HInstruction* BuildStoreKeyedPixelArrayElement(HValue* object,
- HValue* key,
- HValue* val,
- Expression* expr);
+ HInstruction* BuildStoreKeyedSpecializedArrayElement(
+ HValue* object,
+ HValue* key,
+ HValue* val,
+ Assignment* expr);
HValue* BuildContextChainWalk(Variable* var);
diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h
index f7be363..1da3f81 100644
--- a/src/ia32/assembler-ia32-inl.h
+++ b/src/ia32/assembler-ia32-inl.h
@@ -300,7 +300,7 @@
void Assembler::emit(Handle<Object> handle) {
// Verify all Objects referred by code are NOT in new space.
Object* obj = *handle;
- ASSERT(!HEAP->InNewSpace(obj));
+ ASSERT(!isolate()->heap()->InNewSpace(obj));
if (obj->IsHeapObject()) {
emit(reinterpret_cast<intptr_t>(handle.location()),
RelocInfo::EMBEDDED_OBJECT);
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index 311ac39..e6d245e 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -122,9 +122,10 @@
CodeDesc desc;
assm.GetCode(&desc);
Object* code;
- { MaybeObject* maybe_code = HEAP->CreateCode(desc,
- Code::ComputeFlags(Code::STUB),
- Handle<Code>::null());
+ { MaybeObject* maybe_code =
+ assm.isolate()->heap()->CreateCode(desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Code>::null());
if (!maybe_code->ToObject(&code)) return;
}
if (!code->IsCode()) return;
@@ -368,8 +369,6 @@
desc->instr_size = pc_offset();
desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
desc->origin = this;
-
- COUNTERS->reloc_info_size()->Increment(desc->reloc_size);
}
@@ -2178,6 +2177,17 @@
}
+void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
+ ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0xF2);
+ EMIT(0x0F);
+ EMIT(0x5A);
+ emit_sse_operand(dst, src);
+}
+
+
void Assembler::addsd(XMMRegister dst, XMMRegister src) {
ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
EnsureSpace ensure_space(this);
@@ -2422,6 +2432,39 @@
}
+void Assembler::movss(const Operand& dst, XMMRegister src ) {
+ ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0xF3); // float
+ EMIT(0x0F);
+ EMIT(0x11); // store
+ emit_sse_operand(src, dst);
+}
+
+
+void Assembler::movss(XMMRegister dst, const Operand& src) {
+ ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0xF3); // float
+ EMIT(0x0F);
+ EMIT(0x10); // load
+ emit_sse_operand(dst, src);
+}
+
+
+void Assembler::movss(XMMRegister dst, XMMRegister src) {
+ ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ EMIT(0xF3);
+ EMIT(0x0F);
+ EMIT(0x10);
+ emit_sse_operand(dst, src);
+}
+
+
void Assembler::movd(XMMRegister dst, const Operand& src) {
ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
EnsureSpace ensure_space(this);
@@ -2630,7 +2673,7 @@
// Some internal data structures overflow for very large buffers,
// they must ensure that kMaximalBufferSize is not too large.
if ((desc.buffer_size > kMaximalBufferSize) ||
- (desc.buffer_size > HEAP->MaxOldGenerationSize())) {
+ (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
}
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 19d879b..8e0c762 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -904,6 +904,7 @@
void cvtsi2sd(XMMRegister dst, const Operand& src);
void cvtss2sd(XMMRegister dst, XMMRegister src);
+ void cvtsd2ss(XMMRegister dst, XMMRegister src);
void addsd(XMMRegister dst, XMMRegister src);
void subsd(XMMRegister dst, XMMRegister src);
@@ -934,6 +935,10 @@
void movd(const Operand& src, XMMRegister dst);
void movsd(XMMRegister dst, XMMRegister src);
+ void movss(XMMRegister dst, const Operand& src);
+ void movss(const Operand& src, XMMRegister dst);
+ void movss(XMMRegister dst, XMMRegister src);
+
void pand(XMMRegister dst, XMMRegister src);
void pxor(XMMRegister dst, XMMRegister src);
void por(XMMRegister dst, XMMRegister src);
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index cb41646..2970a0e 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -100,8 +100,9 @@
// Set expected number of arguments to zero (not changing eax).
__ Set(ebx, Immediate(0));
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
- __ jmp(Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+ Handle<Code> arguments_adaptor =
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+ __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET);
}
@@ -184,7 +185,8 @@
// ebx: JSObject
// edi: start of next object
__ mov(Operand(ebx, JSObject::kMapOffset), eax);
- __ mov(ecx, FACTORY->empty_fixed_array());
+ Factory* factory = masm->isolate()->factory();
+ __ mov(ecx, factory->empty_fixed_array());
__ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);
__ mov(Operand(ebx, JSObject::kElementsOffset), ecx);
// Set extra fields in the newly allocated object.
@@ -194,9 +196,9 @@
{ Label loop, entry;
// To allow for truncation.
if (count_constructions) {
- __ mov(edx, FACTORY->one_pointer_filler_map());
+ __ mov(edx, factory->one_pointer_filler_map());
} else {
- __ mov(edx, FACTORY->undefined_value());
+ __ mov(edx, factory->undefined_value());
}
__ lea(ecx, Operand(ebx, JSObject::kHeaderSize));
__ jmp(&entry);
@@ -252,7 +254,7 @@
// edi: FixedArray
// edx: number of elements
// ecx: start of next object
- __ mov(eax, FACTORY->fixed_array_map());
+ __ mov(eax, factory->fixed_array_map());
__ mov(Operand(edi, FixedArray::kMapOffset), eax); // setup the map
__ SmiTag(edx);
__ mov(Operand(edi, FixedArray::kLengthOffset), edx); // and length
@@ -262,7 +264,7 @@
// edi: FixedArray
// ecx: start of next object
{ Label loop, entry;
- __ mov(edx, FACTORY->undefined_value());
+ __ mov(edx, factory->undefined_value());
__ lea(eax, Operand(edi, FixedArray::kHeaderSize));
__ jmp(&entry);
__ bind(&loop);
@@ -334,8 +336,8 @@
// Call the function.
if (is_api_function) {
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
- Handle<Code> code = Handle<Code>(
- masm->isolate()->builtins()->builtin(Builtins::HandleApiCallConstruct));
+ Handle<Code> code =
+ masm->isolate()->builtins()->HandleApiCallConstruct();
ParameterCount expected(0);
__ InvokeCode(code, expected, expected,
RelocInfo::CODE_TARGET, CALL_FUNCTION);
@@ -376,7 +378,7 @@
__ pop(ecx);
__ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
__ push(ecx);
- __ IncrementCounter(COUNTERS->constructed_objects(), 1);
+ __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
__ ret(0);
}
@@ -436,8 +438,8 @@
// Invoke the code.
if (is_construct) {
- __ call(Handle<Code>(masm->isolate()->builtins()->builtin(
- Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
+ __ call(masm->isolate()->builtins()->JSConstructCall(),
+ RelocInfo::CODE_TARGET);
} else {
ParameterCount actual(eax);
__ InvokeFunction(edi, actual, CALL_FUNCTION);
@@ -561,12 +563,14 @@
void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
+ Factory* factory = masm->isolate()->factory();
+
// 1. Make sure we have at least one argument.
{ Label done;
__ test(eax, Operand(eax));
__ j(not_zero, &done, taken);
__ pop(ebx);
- __ push(Immediate(FACTORY->undefined_value()));
+ __ push(Immediate(factory->undefined_value()));
__ push(ebx);
__ inc(eax);
__ bind(&done);
@@ -600,9 +604,9 @@
__ test(ebx, Immediate(kSmiTagMask));
__ j(zero, &convert_to_object);
- __ cmp(ebx, FACTORY->null_value());
+ __ cmp(ebx, factory->null_value());
__ j(equal, &use_global_receiver);
- __ cmp(ebx, FACTORY->undefined_value());
+ __ cmp(ebx, factory->undefined_value());
__ j(equal, &use_global_receiver);
// We don't use IsObjectJSObjectType here because we jump on success.
@@ -674,8 +678,8 @@
__ j(not_zero, &function, taken);
__ Set(ebx, Immediate(0));
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
- __ jmp(Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+ __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
__ bind(&function);
}
@@ -688,8 +692,8 @@
__ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
__ SmiUntag(ebx);
__ cmp(eax, Operand(ebx));
- __ j(not_equal, Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)));
+ __ j(not_equal,
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline());
ParameterCount expected(0);
__ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
@@ -754,9 +758,10 @@
// Compute the receiver in non-strict mode.
__ test(ebx, Immediate(kSmiTagMask));
__ j(zero, &call_to_object);
- __ cmp(ebx, FACTORY->null_value());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(ebx, factory->null_value());
__ j(equal, &use_global_receiver);
- __ cmp(ebx, FACTORY->undefined_value());
+ __ cmp(ebx, factory->undefined_value());
__ j(equal, &use_global_receiver);
// If given receiver is already a JavaScript object then there's no
@@ -796,8 +801,7 @@
__ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments
// Use inline caching to speed up access to arguments.
- Handle<Code> ic(masm->isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize();
__ call(ic, RelocInfo::CODE_TARGET);
// It is important that we do not have a test instruction after the
// call. A test instruction after the call is used to indicate that
@@ -868,8 +872,9 @@
// scratch1: initial map
// scratch2: start of next object
__ mov(FieldOperand(result, JSObject::kMapOffset), scratch1);
+ Factory* factory = masm->isolate()->factory();
__ mov(FieldOperand(result, JSArray::kPropertiesOffset),
- FACTORY->empty_fixed_array());
+ factory->empty_fixed_array());
// Field JSArray::kElementsOffset is initialized later.
__ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0));
@@ -877,7 +882,7 @@
// fixed array.
if (initial_capacity == 0) {
__ mov(FieldOperand(result, JSArray::kElementsOffset),
- FACTORY->empty_fixed_array());
+ factory->empty_fixed_array());
return;
}
@@ -894,7 +899,7 @@
// scratch1: elements array
// scratch2: start of next object
__ mov(FieldOperand(scratch1, FixedArray::kMapOffset),
- FACTORY->fixed_array_map());
+ factory->fixed_array_map());
__ mov(FieldOperand(scratch1, FixedArray::kLengthOffset),
Immediate(Smi::FromInt(initial_capacity)));
@@ -905,7 +910,7 @@
if (initial_capacity <= kLoopUnfoldLimit) {
// Use a scratch register here to have only one reloc info when unfolding
// the loop.
- __ mov(scratch3, FACTORY->the_hole_value());
+ __ mov(scratch3, factory->the_hole_value());
for (int i = 0; i < initial_capacity; i++) {
__ mov(FieldOperand(scratch1,
FixedArray::kHeaderSize + i * kPointerSize),
@@ -915,7 +920,7 @@
Label loop, entry;
__ jmp(&entry);
__ bind(&loop);
- __ mov(Operand(scratch1, 0), FACTORY->the_hole_value());
+ __ mov(Operand(scratch1, 0), factory->the_hole_value());
__ add(Operand(scratch1), Immediate(kPointerSize));
__ bind(&entry);
__ cmp(scratch1, Operand(scratch2));
@@ -970,7 +975,8 @@
// elements_array_end: start of next object
// array_size: size of array (smi)
__ mov(FieldOperand(result, JSObject::kMapOffset), elements_array);
- __ mov(elements_array, FACTORY->empty_fixed_array());
+ Factory* factory = masm->isolate()->factory();
+ __ mov(elements_array, factory->empty_fixed_array());
__ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
// Field JSArray::kElementsOffset is initialized later.
__ mov(FieldOperand(result, JSArray::kLengthOffset), array_size);
@@ -989,7 +995,7 @@
// elements_array_end: start of next object
// array_size: size of array (smi)
__ mov(FieldOperand(elements_array, FixedArray::kMapOffset),
- FACTORY->fixed_array_map());
+ factory->fixed_array_map());
// For non-empty JSArrays the length of the FixedArray and the JSArray is the
// same.
__ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size);
@@ -1001,7 +1007,7 @@
__ SmiUntag(array_size);
__ lea(edi, Operand(elements_array,
FixedArray::kHeaderSize - kHeapObjectTag));
- __ mov(eax, FACTORY->the_hole_value());
+ __ mov(eax, factory->the_hole_value());
__ cld();
// Do not use rep stos when filling less than kRepStosThreshold
// words.
@@ -1065,7 +1071,7 @@
edi,
kPreallocatedArrayElements,
&prepare_generic_code_call);
- __ IncrementCounter(COUNTERS->array_function_native(), 1);
+ __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1);
__ pop(ebx);
if (construct_call) {
__ pop(edi);
@@ -1121,7 +1127,8 @@
edi,
true,
&prepare_generic_code_call);
- __ IncrementCounter(COUNTERS->array_function_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->array_function_native(), 1);
__ mov(eax, ebx);
__ pop(ebx);
if (construct_call) {
@@ -1148,7 +1155,7 @@
edi,
false,
&prepare_generic_code_call);
- __ IncrementCounter(COUNTERS->array_function_native(), 1);
+ __ IncrementCounter(counters->array_function_native(), 1);
__ mov(eax, ebx);
__ pop(ebx);
if (construct_call) {
@@ -1234,8 +1241,8 @@
// Jump to the generic array code in case the specialized code cannot handle
// the construction.
__ bind(&generic_array_code);
- Code* code = masm->isolate()->builtins()->builtin(Builtins::ArrayCodeGeneric);
- Handle<Code> array_code(code);
+ Handle<Code> array_code =
+ masm->isolate()->builtins()->ArrayCodeGeneric();
__ jmp(array_code, RelocInfo::CODE_TARGET);
}
@@ -1268,9 +1275,8 @@
// Jump to the generic construct code in case the specialized code cannot
// handle the construction.
__ bind(&generic_constructor);
- Code* code = masm->isolate()->builtins()->builtin(
- Builtins::JSConstructStubGeneric);
- Handle<Code> generic_construct_stub(code);
+ Handle<Code> generic_construct_stub =
+ masm->isolate()->builtins()->JSConstructStubGeneric();
__ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
}
@@ -1283,7 +1289,8 @@
// -- esp[(argc - n) * 4] : arg[n] (zero-based)
// -- esp[(argc + 1) * 4] : receiver
// -----------------------------------
- __ IncrementCounter(COUNTERS->string_ctor_calls(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->string_ctor_calls(), 1);
if (FLAG_debug_code) {
__ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx);
@@ -1312,7 +1319,7 @@
edx, // Scratch 2.
false, // Input is known to be smi?
¬_cached);
- __ IncrementCounter(COUNTERS->string_ctor_cached_number(), 1);
+ __ IncrementCounter(counters->string_ctor_cached_number(), 1);
__ bind(&argument_is_string);
// ----------- S t a t e -------------
// -- ebx : argument converted to string
@@ -1341,7 +1348,8 @@
__ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx);
// Set properties and elements.
- __ Set(ecx, Immediate(FACTORY->empty_fixed_array()));
+ Factory* factory = masm->isolate()->factory();
+ __ Set(ecx, Immediate(factory->empty_fixed_array()));
__ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx);
__ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx);
@@ -1364,12 +1372,12 @@
Condition is_string = masm->IsObjectStringType(eax, ebx, ecx);
__ j(NegateCondition(is_string), &convert_argument);
__ mov(ebx, eax);
- __ IncrementCounter(COUNTERS->string_ctor_string_value(), 1);
+ __ IncrementCounter(counters->string_ctor_string_value(), 1);
__ jmp(&argument_is_string);
// Invoke the conversion builtin and put the result into ebx.
__ bind(&convert_argument);
- __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1);
+ __ IncrementCounter(counters->string_ctor_conversions(), 1);
__ EnterInternalFrame();
__ push(edi); // Preserve the function.
__ push(eax);
@@ -1382,7 +1390,7 @@
// Load the empty string into ebx, remove the receiver from the
// stack, and jump back to the case where the argument is a string.
__ bind(&no_arguments);
- __ Set(ebx, Immediate(FACTORY->empty_string()));
+ __ Set(ebx, Immediate(factory->empty_string()));
__ pop(ecx);
__ lea(esp, Operand(esp, kPointerSize));
__ push(ecx);
@@ -1391,7 +1399,7 @@
// At this point the argument is already a string. Call runtime to
// create a string wrapper.
__ bind(&gc_required);
- __ IncrementCounter(COUNTERS->string_ctor_gc_required(), 1);
+ __ IncrementCounter(counters->string_ctor_gc_required(), 1);
__ EnterInternalFrame();
__ push(ebx);
__ CallRuntime(Runtime::kNewStringWrapper, 1);
@@ -1442,7 +1450,7 @@
// -----------------------------------
Label invoke, dont_adapt_arguments;
- __ IncrementCounter(COUNTERS->arguments_adaptors(), 1);
+ __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
Label enough, too_few;
__ cmp(eax, Operand(ebx));
@@ -1490,7 +1498,7 @@
Label fill;
__ bind(&fill);
__ inc(ecx);
- __ push(Immediate(FACTORY->undefined_value()));
+ __ push(Immediate(masm->isolate()->factory()->undefined_value()));
__ cmp(ecx, Operand(ebx));
__ j(less, &fill);
@@ -1586,7 +1594,7 @@
#undef __
-
-} } // namespace v8::internal
+}
+} // namespace v8::internal
#endif // V8_TARGET_ARCH_IA32
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index eaff1b8..711616f 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -49,7 +49,8 @@
__ bind(&check_heap_number);
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ cmp(Operand(ebx), Immediate(FACTORY->heap_number_map()));
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(Operand(ebx), Immediate(factory->heap_number_map()));
__ j(not_equal, &call_builtin);
__ ret(0);
@@ -83,16 +84,17 @@
// Initialize the rest of the function. We don't have to update the
// write barrier because the allocated object is in new space.
- __ mov(ebx, Immediate(FACTORY->empty_fixed_array()));
+ Factory* factory = masm->isolate()->factory();
+ __ mov(ebx, Immediate(factory->empty_fixed_array()));
__ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ebx);
__ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
__ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset),
- Immediate(FACTORY->the_hole_value()));
+ Immediate(factory->the_hole_value()));
__ mov(FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset), edx);
__ mov(FieldOperand(eax, JSFunction::kContextOffset), esi);
__ mov(FieldOperand(eax, JSFunction::kLiteralsOffset), ebx);
__ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset),
- Immediate(FACTORY->undefined_value()));
+ Immediate(factory->undefined_value()));
// Initialize the code pointer in the function to be the one
// found in the shared function info object.
@@ -109,7 +111,7 @@
__ pop(edx);
__ push(esi);
__ push(edx);
- __ push(Immediate(FACTORY->false_value()));
+ __ push(Immediate(factory->false_value()));
__ push(ecx); // Restore return address.
__ TailCallRuntime(Runtime::kNewClosure, 3, 1);
}
@@ -126,7 +128,8 @@
__ mov(ecx, Operand(esp, 1 * kPointerSize));
// Setup the object header.
- __ mov(FieldOperand(eax, HeapObject::kMapOffset), FACTORY->context_map());
+ Factory* factory = masm->isolate()->factory();
+ __ mov(FieldOperand(eax, HeapObject::kMapOffset), factory->context_map());
__ mov(FieldOperand(eax, Context::kLengthOffset),
Immediate(Smi::FromInt(length)));
@@ -145,7 +148,7 @@
__ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
// Initialize the rest of the slots to undefined.
- __ mov(ebx, FACTORY->undefined_value());
+ __ mov(ebx, factory->undefined_value());
for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
__ mov(Operand(eax, Context::SlotOffset(i)), ebx);
}
@@ -181,7 +184,8 @@
STATIC_ASSERT(kSmiTag == 0);
__ mov(ecx, FieldOperand(ecx, eax, times_half_pointer_size,
FixedArray::kHeaderSize));
- __ cmp(ecx, FACTORY->undefined_value());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(ecx, factory->undefined_value());
__ j(equal, &slow_case);
if (FLAG_debug_code) {
@@ -189,11 +193,11 @@
Handle<Map> expected_map;
if (mode_ == CLONE_ELEMENTS) {
message = "Expected (writable) fixed array";
- expected_map = FACTORY->fixed_array_map();
+ expected_map = factory->fixed_array_map();
} else {
ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS);
message = "Expected copy-on-write fixed array";
- expected_map = FACTORY->fixed_cow_array_map();
+ expected_map = factory->fixed_cow_array_map();
}
__ push(ecx);
__ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset));
@@ -242,7 +246,8 @@
__ mov(eax, Operand(esp, 1 * kPointerSize));
// 'null' => false.
- __ cmp(eax, FACTORY->null_value());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(eax, factory->null_value());
__ j(equal, &false_result);
// Get the map and type of the heap object.
@@ -268,7 +273,7 @@
__ bind(¬_string);
// HeapNumber => false iff +0, -0, or NaN.
- __ cmp(edx, FACTORY->heap_number_map());
+ __ cmp(edx, factory->heap_number_map());
__ j(not_equal, &true_result);
__ fldz();
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
@@ -364,7 +369,8 @@
// Update flags to indicate that arguments are in registers.
SetArgsInRegisters();
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+ __ IncrementCounter(
+ masm->isolate()->counters()->generic_binary_stub_calls_regs(), 1);
}
// Call the stub.
@@ -400,7 +406,8 @@
// Update flags to indicate that arguments are in registers.
SetArgsInRegisters();
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+ __ IncrementCounter(
+ masm->isolate()->counters()->generic_binary_stub_calls_regs(), 1);
}
// Call the stub.
@@ -435,7 +442,8 @@
}
// Update flags to indicate that arguments are in registers.
SetArgsInRegisters();
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
}
// Call the stub.
@@ -878,7 +886,8 @@
void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
Label call_runtime;
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->generic_binary_stub_calls(), 1);
if (runtime_operands_type_ == BinaryOpIC::UNINIT_OR_SMI) {
Label slow;
@@ -2200,7 +2209,8 @@
void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
Label call_runtime;
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->generic_binary_stub_calls(), 1);
switch (op_) {
case Token::ADD:
@@ -2516,7 +2526,8 @@
__ bind(&input_not_smi);
// Check if input is a HeapNumber.
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ cmp(Operand(ebx), Immediate(FACTORY->heap_number_map()));
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(Operand(ebx), Immediate(factory->heap_number_map()));
__ j(not_equal, &runtime_call);
// Input is a HeapNumber. Push it on the FPU stack and load its
// low and high words into ebx, edx.
@@ -2984,14 +2995,15 @@
// If the argument is undefined it converts to zero (ECMA-262, section 9.5).
__ bind(&check_undefined_arg1);
- __ cmp(edx, FACTORY->undefined_value());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(edx, factory->undefined_value());
__ j(not_equal, conversion_failure);
__ mov(edx, Immediate(0));
__ jmp(&load_arg2);
__ bind(&arg1_is_object);
__ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
- __ cmp(ebx, FACTORY->heap_number_map());
+ __ cmp(ebx, factory->heap_number_map());
__ j(not_equal, &check_undefined_arg1);
// Get the untagged integer version of the edx heap number in ecx.
@@ -3015,14 +3027,14 @@
// If the argument is undefined it converts to zero (ECMA-262, section 9.5).
__ bind(&check_undefined_arg2);
- __ cmp(eax, FACTORY->undefined_value());
+ __ cmp(eax, factory->undefined_value());
__ j(not_equal, conversion_failure);
__ mov(ecx, Immediate(0));
__ jmp(&done);
__ bind(&arg2_is_object);
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ cmp(ebx, FACTORY->heap_number_map());
+ __ cmp(ebx, factory->heap_number_map());
__ j(not_equal, &check_undefined_arg2);
// Get the untagged integer version of the eax heap number in ecx.
@@ -3109,14 +3121,15 @@
// Load operand in edx into xmm0, or branch to not_numbers.
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &load_smi_edx, not_taken); // Argument in edx is a smi.
- __ cmp(FieldOperand(edx, HeapObject::kMapOffset), FACTORY->heap_number_map());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map());
__ j(not_equal, not_numbers); // Argument in edx is not a number.
__ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
__ bind(&load_eax);
// Load operand in eax into xmm1, or branch to not_numbers.
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &load_smi_eax, not_taken); // Argument in eax is a smi.
- __ cmp(FieldOperand(eax, HeapObject::kMapOffset), FACTORY->heap_number_map());
+ __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map());
__ j(equal, &load_float_eax);
__ jmp(not_numbers); // Argument in eax is not a number.
__ bind(&load_smi_edx);
@@ -3234,14 +3247,15 @@
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &test_other, not_taken); // argument in edx is OK
__ mov(scratch, FieldOperand(edx, HeapObject::kMapOffset));
- __ cmp(scratch, FACTORY->heap_number_map());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(scratch, factory->heap_number_map());
__ j(not_equal, non_float); // argument in edx is not a number -> NaN
__ bind(&test_other);
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &done); // argument in eax is OK
__ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
- __ cmp(scratch, FACTORY->heap_number_map());
+ __ cmp(scratch, factory->heap_number_map());
__ j(not_equal, non_float); // argument in eax is not a number -> NaN
// Fall-through: Both operands are numbers.
@@ -3287,7 +3301,7 @@
}
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
- __ cmp(edx, FACTORY->heap_number_map());
+ __ cmp(edx, masm->isolate()->factory()->heap_number_map());
__ j(not_equal, &slow);
if (overwrite_ == UNARY_OVERWRITE) {
__ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
@@ -3319,7 +3333,7 @@
// Check if the operand is a heap number.
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
- __ cmp(edx, FACTORY->heap_number_map());
+ __ cmp(edx, masm->isolate()->factory()->heap_number_map());
__ j(not_equal, &slow, not_taken);
// Convert the heap number in eax to an untagged integer in ecx.
@@ -3421,8 +3435,9 @@
__ jmp(&powi);
// exponent is smi and base is a heapnumber.
__ bind(&base_nonsmi);
+ Factory* factory = masm->isolate()->factory();
__ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- FACTORY->heap_number_map());
+ factory->heap_number_map());
__ j(not_equal, &call_runtime);
__ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
@@ -3474,7 +3489,7 @@
// on doubles.
__ bind(&exponent_nonsmi);
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
- FACTORY->heap_number_map());
+ factory->heap_number_map());
__ j(not_equal, &call_runtime);
__ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
// Test if exponent is nan.
@@ -3491,7 +3506,7 @@
__ bind(&base_not_smi);
__ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- FACTORY->heap_number_map());
+ factory->heap_number_map());
__ j(not_equal, &call_runtime);
__ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
__ and_(ecx, HeapNumber::kExponentMask);
@@ -3689,7 +3704,7 @@
__ lea(edi, Operand(eax, GetArgumentsObjectSize()));
__ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
__ mov(FieldOperand(edi, FixedArray::kMapOffset),
- Immediate(FACTORY->fixed_array_map()));
+ Immediate(masm->isolate()->factory()->fixed_array_map()));
__ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
// Untag the length for the loop below.
@@ -3818,7 +3833,8 @@
// Check that the JSArray is in fast case.
__ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
__ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset));
- __ cmp(eax, FACTORY->fixed_array_map());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(eax, factory->fixed_array_map());
__ j(not_equal, &runtime);
// Check that the last match info has space for the capture registers and the
// additional information.
@@ -3856,7 +3872,7 @@
__ j(not_zero, &runtime);
// String is a cons string.
__ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
- __ cmp(Operand(edx), FACTORY->empty_string());
+ __ cmp(Operand(edx), factory->empty_string());
__ j(not_equal, &runtime);
__ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
@@ -3906,7 +3922,8 @@
// edx: code
// edi: encoding of subject string (1 if ascii 0 if two_byte);
// All checks done. Now push arguments for native regexp code.
- __ IncrementCounter(COUNTERS->regexp_entry_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->regexp_entry_native(), 1);
// Isolates: note we add an additional parameter here (isolate pointer).
static const int kRegExpExecuteArguments = 8;
@@ -3994,7 +4011,7 @@
// Special handling of termination exceptions which are uncatchable
// by javascript code.
- __ cmp(eax, FACTORY->termination_exception());
+ __ cmp(eax, factory->termination_exception());
Label throw_termination_exception;
__ j(equal, &throw_termination_exception);
@@ -4006,7 +4023,7 @@
__ bind(&failure);
// For failure to match, return null.
- __ mov(Operand(eax), FACTORY->null_value());
+ __ mov(Operand(eax), factory->null_value());
__ ret(4 * kPointerSize);
// Load RegExp data.
@@ -4107,7 +4124,8 @@
// Set elements to point to FixedArray allocated right after the JSArray.
// Interleave operations for better latency.
__ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
- __ mov(ecx, Immediate(FACTORY->empty_fixed_array()));
+ Factory* factory = masm->isolate()->factory();
+ __ mov(ecx, Immediate(factory->empty_fixed_array()));
__ lea(ebx, Operand(eax, JSRegExpResult::kSize));
__ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
__ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
@@ -4130,12 +4148,12 @@
// Set map.
__ mov(FieldOperand(ebx, HeapObject::kMapOffset),
- Immediate(FACTORY->fixed_array_map()));
+ Immediate(factory->fixed_array_map()));
// Set length.
__ mov(FieldOperand(ebx, FixedArray::kLengthOffset), ecx);
// Fill contents of fixed-array with the-hole.
__ SmiUntag(ecx);
- __ mov(edx, Immediate(FACTORY->the_hole_value()));
+ __ mov(edx, Immediate(factory->the_hole_value()));
__ lea(ebx, FieldOperand(ebx, FixedArray::kHeaderSize));
// Fill fixed array elements with hole.
// eax: JSArray.
@@ -4201,7 +4219,7 @@
__ jmp(&smi_hash_calculated);
__ bind(¬_smi);
__ cmp(FieldOperand(object, HeapObject::kMapOffset),
- FACTORY->heap_number_map());
+ masm->isolate()->factory()->heap_number_map());
__ j(not_equal, not_found);
STATIC_ASSERT(8 == kDoubleSize);
__ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset));
@@ -4251,7 +4269,8 @@
index,
times_twice_pointer_size,
FixedArray::kHeaderSize + kPointerSize));
- __ IncrementCounter(COUNTERS->number_to_string_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->number_to_string_native(), 1);
}
@@ -4317,14 +4336,14 @@
// Check for undefined. undefined OP undefined is false even though
// undefined == undefined.
NearLabel check_for_nan;
- __ cmp(edx, FACTORY->undefined_value());
+ __ cmp(edx, masm->isolate()->factory()->undefined_value());
__ j(not_equal, &check_for_nan);
__ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
__ ret(0);
__ bind(&check_for_nan);
}
- // Test for NaN. Sadly, we can't just compare to FACTORY->nan_value(),
+ // Test for NaN. Sadly, we can't just compare to factory->nan_value(),
// so we do the second best thing - test it ourselves.
// Note: if cc_ != equal, never_nan_nan_ is not used.
if (never_nan_nan_ && (cc_ == equal)) {
@@ -4333,7 +4352,7 @@
} else {
NearLabel heap_number;
__ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- Immediate(FACTORY->heap_number_map()));
+ Immediate(masm->isolate()->factory()->heap_number_map()));
__ j(equal, &heap_number);
if (cc_ != equal) {
// Call runtime on identical JSObjects. Otherwise return equal.
@@ -4410,7 +4429,7 @@
// Check if the non-smi operand is a heap number.
__ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
- Immediate(FACTORY->heap_number_map()));
+ Immediate(masm->isolate()->factory()->heap_number_map()));
// If heap number, handle it in the slow case.
__ j(equal, &slow);
// Return non-equal (ebx is not zero)
@@ -4674,8 +4693,8 @@
__ Set(eax, Immediate(argc_));
__ Set(ebx, Immediate(0));
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
- Handle<Code> adaptor(masm->isolate()->builtins()->builtin(
- Builtins::ArgumentsAdaptorTrampoline));
+ Handle<Code> adaptor =
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
__ jmp(adaptor, RelocInfo::CODE_TARGET);
}
@@ -4742,7 +4761,7 @@
// call as this may lead to crashes in the IC code later.
if (FLAG_debug_code) {
NearLabel okay;
- __ cmp(eax, FACTORY->the_hole_value());
+ __ cmp(eax, masm->isolate()->factory()->the_hole_value());
__ j(not_equal, &okay);
__ int3();
__ bind(&okay);
@@ -4800,7 +4819,7 @@
// Special handling of termination exceptions which are uncatchable
// by javascript code.
- __ cmp(eax, FACTORY->termination_exception());
+ __ cmp(eax, masm->isolate()->factory()->termination_exception());
__ j(equal, throw_termination_exception);
// Handle normal exception.
@@ -4943,11 +4962,11 @@
// stub, because the builtin stubs may not have been generated yet.
if (is_construct) {
ExternalReference construct_entry(
- Builtins::JSConstructEntryTrampoline,
+ Builtins::kJSConstructEntryTrampoline,
masm->isolate());
__ mov(edx, Immediate(construct_entry));
} else {
- ExternalReference entry(Builtins::JSEntryTrampoline,
+ ExternalReference entry(Builtins::kJSEntryTrampoline,
masm->isolate());
__ mov(edx, Immediate(entry));
}
@@ -5101,7 +5120,8 @@
__ bind(&loop);
__ cmp(scratch, Operand(prototype));
__ j(equal, &is_instance);
- __ cmp(Operand(scratch), Immediate(FACTORY->null_value()));
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(Operand(scratch), Immediate(factory->null_value()));
__ j(equal, &is_not_instance);
__ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
__ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
@@ -5115,7 +5135,7 @@
times_pointer_size, roots_address), eax);
} else {
// Get return address and delta to inlined map check.
- __ mov(eax, FACTORY->true_value());
+ __ mov(eax, factory->true_value());
__ mov(scratch, Operand(esp, 0 * kPointerSize));
__ sub(scratch, Operand(esp, 1 * kPointerSize));
if (FLAG_debug_code) {
@@ -5137,7 +5157,7 @@
scratch, times_pointer_size, roots_address), eax);
} else {
// Get return address and delta to inlined map check.
- __ mov(eax, FACTORY->false_value());
+ __ mov(eax, factory->false_value());
__ mov(scratch, Operand(esp, 0 * kPointerSize));
__ sub(scratch, Operand(esp, 1 * kPointerSize));
if (FLAG_debug_code) {
@@ -5161,7 +5181,7 @@
__ j(not_equal, &slow, not_taken);
// Null is not instance of anything.
- __ cmp(object, FACTORY->null_value());
+ __ cmp(object, factory->null_value());
__ j(not_equal, &object_not_null);
__ Set(eax, Immediate(Smi::FromInt(1)));
__ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
@@ -5202,10 +5222,10 @@
NearLabel true_value, done;
__ test(eax, Operand(eax));
__ j(zero, &true_value);
- __ mov(eax, FACTORY->false_value());
+ __ mov(eax, factory->false_value());
__ jmp(&done);
__ bind(&true_value);
- __ mov(eax, FACTORY->true_value());
+ __ mov(eax, factory->true_value());
__ bind(&done);
__ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
}
@@ -5334,7 +5354,7 @@
// the case we would rather go to the runtime system now to flatten
// the string.
__ cmp(FieldOperand(object_, ConsString::kSecondOffset),
- Immediate(FACTORY->empty_string()));
+ Immediate(masm->isolate()->factory()->empty_string()));
__ j(not_equal, &call_runtime_);
// Get the first of the two strings and load its instance type.
__ mov(object_, FieldOperand(object_, ConsString::kFirstOffset));
@@ -5379,7 +5399,10 @@
// Index is not a smi.
__ bind(&index_not_smi_);
// If index is a heap number, try converting it to an integer.
- __ CheckMap(index_, FACTORY->heap_number_map(), index_not_number_, true);
+ __ CheckMap(index_,
+ masm->isolate()->factory()->heap_number_map(),
+ index_not_number_,
+ true);
call_helper.BeforeCall(masm);
__ push(object_);
__ push(index_);
@@ -5440,7 +5463,8 @@
((~String::kMaxAsciiCharCode) << kSmiTagSize)));
__ j(not_zero, &slow_case_, not_taken);
- __ Set(result_, Immediate(FACTORY->single_character_string_cache()));
+ Factory* factory = masm->isolate()->factory();
+ __ Set(result_, Immediate(factory->single_character_string_cache()));
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
STATIC_ASSERT(kSmiShiftSize == 0);
@@ -5448,7 +5472,7 @@
__ mov(result_, FieldOperand(result_,
code_, times_half_pointer_size,
FixedArray::kHeaderSize));
- __ cmp(result_, FACTORY->undefined_value());
+ __ cmp(result_, factory->undefined_value());
__ j(equal, &slow_case_, not_taken);
__ bind(&exit_);
}
@@ -5534,7 +5558,8 @@
__ test(ecx, Operand(ecx));
__ j(not_zero, &second_not_zero_length);
// Second string is empty, result is first string which is already in eax.
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
__ bind(&second_not_zero_length);
__ mov(ebx, FieldOperand(eax, String::kLengthOffset));
@@ -5543,7 +5568,7 @@
__ j(not_zero, &both_not_zero_length);
// First string is empty, result is second string which is in edx.
__ mov(eax, edx);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
// Both strings are non-empty.
@@ -5577,7 +5602,7 @@
StringHelper::GenerateTwoCharacterSymbolTableProbe(
masm, ebx, ecx, eax, edx, edi,
&make_two_character_string_no_reload, &make_two_character_string);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
// Allocate a two character string.
@@ -5589,7 +5614,7 @@
__ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
__ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
__ bind(&make_two_character_string_no_reload);
- __ IncrementCounter(COUNTERS->string_add_make_two_char(), 1);
+ __ IncrementCounter(counters->string_add_make_two_char(), 1);
__ AllocateAsciiString(eax, // Result.
2, // Length.
edi, // Scratch 1.
@@ -5600,7 +5625,7 @@
__ or_(ebx, Operand(ecx));
// Set the characters in the new string.
__ mov_w(FieldOperand(eax, SeqAsciiString::kHeaderSize), ebx);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
__ bind(&longer_than_two);
@@ -5631,7 +5656,7 @@
__ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax);
__ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx);
__ mov(eax, ecx);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
__ bind(&non_ascii);
// At least one of the strings is two-byte. Check whether it happens
@@ -5708,7 +5733,7 @@
// edx: first char of second argument
// edi: length of second argument
StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
// Handle creating a flat two byte result.
@@ -5749,7 +5774,7 @@
// edx: first char of second argument
// edi: length of second argument
StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
// Just jump to runtime to add the two strings.
@@ -5975,9 +6000,10 @@
SymbolTable::kElementsStartOffset));
// If entry is undefined no string with this hash can be found.
- __ cmp(candidate, FACTORY->undefined_value());
+ Factory* factory = masm->isolate()->factory();
+ __ cmp(candidate, factory->undefined_value());
__ j(equal, not_found);
- __ cmp(candidate, FACTORY->null_value());
+ __ cmp(candidate, factory->null_value());
__ j(equal, &next_probe[i]);
// If length is not 2 the string is not a candidate.
@@ -6174,7 +6200,8 @@
// esi: character of sub string start
StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true);
__ mov(esi, edx); // Restore esi.
- __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->sub_string_native(), 1);
__ ret(3 * kPointerSize);
__ bind(&non_ascii_flat);
@@ -6215,7 +6242,7 @@
__ mov(esi, edx); // Restore esi.
__ bind(&return_eax);
- __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+ __ IncrementCounter(counters->sub_string_native(), 1);
__ ret(3 * kPointerSize);
// Just jump to runtime to create the sub string.
@@ -6234,7 +6261,8 @@
Label result_greater;
Label compare_lengths;
- __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->string_compare_native(), 1);
// Find minimum length.
NearLabel left_shorter;
@@ -6325,7 +6353,7 @@
STATIC_ASSERT(EQUAL == 0);
STATIC_ASSERT(kSmiTag == 0);
__ Set(eax, Immediate(Smi::FromInt(EQUAL)));
- __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+ __ IncrementCounter(masm->isolate()->counters()->string_compare_native(), 1);
__ ret(2 * kPointerSize);
__ bind(¬_same);
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 7e93493..cf990a0 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -3347,7 +3347,7 @@
__ mov(ecx, FieldOperand(eax, JSFunction::kCodeEntryOffset));
__ sub(Operand(ecx), Immediate(Code::kHeaderSize - kHeapObjectTag));
Handle<Code> apply_code(masm()->isolate()->builtins()->builtin(
- Builtins::FunctionApply));
+ Builtins::kFunctionApply));
__ cmp(Operand(ecx), Immediate(apply_code));
__ j(not_equal, &build_args);
@@ -5696,7 +5696,8 @@
FastCloneShallowArrayStub stub(
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
clone = frame_->CallStub(&stub, 3);
- __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->cow_arrays_created_stub(), 1);
} else if (node->depth() > 1) {
clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
} else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
@@ -9392,7 +9393,7 @@
}
__ Set(ecx, Immediate(name_));
Handle<Code> ic(masm()->isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Builtins::kLoadIC_Initialize));
RelocInfo::Mode mode = is_contextual_
? RelocInfo::CODE_TARGET_CONTEXT
: RelocInfo::CODE_TARGET;
@@ -9409,15 +9410,16 @@
int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
// Here we use masm_-> instead of the __ macro because this is the
// instruction that gets patched and coverage code gets in the way.
+ Counters* counters = masm()->isolate()->counters();
if (is_contextual_) {
masm_->mov(is_dont_delete_ ? edx : ecx, -delta_to_patch_site);
- __ IncrementCounter(COUNTERS->named_load_global_inline_miss(), 1);
+ __ IncrementCounter(counters->named_load_global_inline_miss(), 1);
if (is_dont_delete_) {
- __ IncrementCounter(COUNTERS->dont_delete_hint_miss(), 1);
+ __ IncrementCounter(counters->dont_delete_hint_miss(), 1);
}
} else {
masm_->test(eax, Immediate(-delta_to_patch_site));
- __ IncrementCounter(COUNTERS->named_load_inline_miss(), 1);
+ __ IncrementCounter(counters->named_load_inline_miss(), 1);
}
if (!dst_.is(eax)) __ mov(dst_, eax);
@@ -9472,7 +9474,7 @@
// This means that we cannot allow test instructions after calls to
// KeyedLoadIC stubs in other places.
Handle<Code> ic(masm()->isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Builtins::kKeyedLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
// The delta from the start of the map-compare instruction to the
// test instruction. We use masm_-> directly here instead of the __
@@ -9483,7 +9485,8 @@
// Here we use masm_-> instead of the __ macro because this is the
// instruction that gets patched and coverage code gets in the way.
masm_->test(eax, Immediate(-delta_to_patch_site));
- __ IncrementCounter(COUNTERS->keyed_load_inline_miss(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_inline_miss(), 1);
if (!dst_.is(eax)) __ mov(dst_, eax);
}
@@ -9519,7 +9522,8 @@
void DeferredReferenceSetKeyedValue::Generate() {
- __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_store_inline_miss(), 1);
// Move value_ to eax, key_ to ecx, and receiver_ to edx.
Register old_value = value_;
@@ -9574,8 +9578,8 @@
// Call the IC stub.
Handle<Code> ic(masm()->isolate()->builtins()->builtin(
- (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ (strict_mode_ == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+ : Builtins::kKeyedStoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
// The delta from the start of the map-compare instruction to the
// test instruction. We use masm_-> directly here instead of the
@@ -9596,9 +9600,13 @@
int original_height = frame()->height();
#endif
+ Isolate* isolate = masm()->isolate();
+ Factory* factory = isolate->factory();
+ Counters* counters = isolate->counters();
+
bool contextual_load_in_builtin =
is_contextual &&
- (masm()->isolate()->bootstrapper()->IsActive() ||
+ (isolate->bootstrapper()->IsActive() ||
(!info_->closure().is_null() && info_->closure()->IsBuiltin()));
Result result;
@@ -9644,7 +9652,7 @@
// use the double underscore macro that may insert instructions).
// Initially use an invalid map to force a failure.
masm()->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
- Immediate(FACTORY->null_value()));
+ Immediate(factory->null_value()));
// This branch is always a forwards branch so it's always a fixed size
// which allows the assert below to succeed and patching to work.
deferred->Branch(not_equal);
@@ -9656,15 +9664,15 @@
if (is_contextual) {
// Load the (initialy invalid) cell and get its value.
- masm()->mov(result.reg(), FACTORY->null_value());
+ masm()->mov(result.reg(), factory->null_value());
if (FLAG_debug_code) {
__ cmp(FieldOperand(result.reg(), HeapObject::kMapOffset),
- FACTORY->global_property_cell_map());
+ factory->global_property_cell_map());
__ Assert(equal, "Uninitialized inlined contextual load");
}
__ mov(result.reg(),
FieldOperand(result.reg(), JSGlobalPropertyCell::kValueOffset));
- __ cmp(result.reg(), FACTORY->the_hole_value());
+ __ cmp(result.reg(), factory->the_hole_value());
deferred->Branch(equal);
bool is_dont_delete = false;
if (!info_->closure().is_null()) {
@@ -9684,15 +9692,15 @@
}
deferred->set_is_dont_delete(is_dont_delete);
if (!is_dont_delete) {
- __ cmp(result.reg(), FACTORY->the_hole_value());
+ __ cmp(result.reg(), factory->the_hole_value());
deferred->Branch(equal);
} else if (FLAG_debug_code) {
- __ cmp(result.reg(), FACTORY->the_hole_value());
+ __ cmp(result.reg(), factory->the_hole_value());
__ Check(not_equal, "DontDelete cells can't contain the hole");
}
- __ IncrementCounter(COUNTERS->named_load_global_inline(), 1);
+ __ IncrementCounter(counters->named_load_global_inline(), 1);
if (is_dont_delete) {
- __ IncrementCounter(COUNTERS->dont_delete_hint_hit(), 1);
+ __ IncrementCounter(counters->dont_delete_hint_hit(), 1);
}
} else {
// The initial (invalid) offset has to be large enough to force a 32-bit
@@ -9700,7 +9708,7 @@
// kMaxInt (minus kHeapObjectTag).
int offset = kMaxInt;
masm()->mov(result.reg(), FieldOperand(receiver.reg(), offset));
- __ IncrementCounter(COUNTERS->named_load_inline(), 1);
+ __ IncrementCounter(counters->named_load_inline(), 1);
}
deferred->BindExit();
@@ -9888,7 +9896,7 @@
result = elements;
__ cmp(Operand(result.reg()), Immediate(FACTORY->the_hole_value()));
deferred->Branch(equal);
- __ IncrementCounter(COUNTERS->keyed_load_inline(), 1);
+ __ IncrementCounter(masm_->isolate()->counters()->keyed_load_inline(), 1);
deferred->BindExit();
} else {
@@ -9993,7 +10001,7 @@
// Store the value.
__ mov(FixedArrayElementOperand(tmp.reg(), key.reg()), result.reg());
- __ IncrementCounter(COUNTERS->keyed_store_inline(), 1);
+ __ IncrementCounter(masm_->isolate()->counters()->keyed_store_inline(), 1);
deferred->BindExit();
} else {
@@ -10224,7 +10232,7 @@
__ test(Operand(src), Immediate(0x0F));
__ j(not_zero, &unaligned_source);
{
- __ IncrementCounter(COUNTERS->memcopy_aligned(), 1);
+ __ IncrementCounter(masm.isolate()->counters()->memcopy_aligned(), 1);
// Copy loop for aligned source and destination.
__ mov(edx, count);
Register loop_count = ecx;
@@ -10272,7 +10280,7 @@
// Copy loop for unaligned source and aligned destination.
// If source is not aligned, we can't read it as efficiently.
__ bind(&unaligned_source);
- __ IncrementCounter(COUNTERS->memcopy_unaligned(), 1);
+ __ IncrementCounter(masm.isolate()->counters()->memcopy_unaligned(), 1);
__ mov(edx, ecx);
Register loop_count = ecx;
Register count = edx;
@@ -10316,7 +10324,7 @@
}
} else {
- __ IncrementCounter(COUNTERS->memcopy_noxmm(), 1);
+ __ IncrementCounter(masm.isolate()->counters()->memcopy_noxmm(), 1);
// SSE2 not supported. Unlikely to happen in practice.
__ push(edi);
__ push(esi);
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 4eaf7fe..026572f 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -55,12 +55,89 @@
}
-void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
- HandleScope scope;
- AssertNoAllocation no_allocation;
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+ Isolate* isolate = code->GetIsolate();
+ HandleScope scope(isolate);
+ // Compute the size of relocation information needed for the code
+ // patching in Deoptimizer::DeoptimizeFunction.
+ int min_reloc_size = 0;
+ Address prev_reloc_address = code->instruction_start();
+ Address code_start_address = code->instruction_start();
+ SafepointTable table(*code);
+ for (unsigned i = 0; i < table.length(); ++i) {
+ Address curr_reloc_address = code_start_address + table.GetPcOffset(i);
+ ASSERT_GE(curr_reloc_address, prev_reloc_address);
+ SafepointEntry safepoint_entry = table.GetEntry(i);
+ int deoptimization_index = safepoint_entry.deoptimization_index();
+ if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
+ // The gap code is needed to get to the state expected at the
+ // bailout and we need to skip the call opcode to get to the
+ // address that needs reloc.
+ curr_reloc_address += safepoint_entry.gap_code_size() + 1;
+ int pc_delta = curr_reloc_address - prev_reloc_address;
+ // We use RUNTIME_ENTRY reloc info which has a size of 2 bytes
+ // if encodable with small pc delta encoding and up to 6 bytes
+ // otherwise.
+ if (pc_delta <= RelocInfo::kMaxSmallPCDelta) {
+ min_reloc_size += 2;
+ } else {
+ min_reloc_size += 6;
+ }
+ prev_reloc_address = curr_reloc_address;
+ }
+ }
+
+ // If the relocation information is not big enough we create a new
+ // relocation info object that is padded with comments to make it
+ // big enough for lazy doptimization.
+ int reloc_length = code->relocation_info()->length();
+ if (min_reloc_size > reloc_length) {
+ int comment_reloc_size = RelocInfo::kMinRelocCommentSize;
+ // Padding needed.
+ int min_padding = min_reloc_size - reloc_length;
+ // Number of comments needed to take up at least that much space.
+ int additional_comments =
+ (min_padding + comment_reloc_size - 1) / comment_reloc_size;
+ // Actual padding size.
+ int padding = additional_comments * comment_reloc_size;
+ // Allocate new relocation info and copy old relocation to the end
+ // of the new relocation info array because relocation info is
+ // written and read backwards.
+ Factory* factory = isolate->factory();
+ Handle<ByteArray> new_reloc =
+ factory->NewByteArray(reloc_length + padding, TENURED);
+ memcpy(new_reloc->GetDataStartAddress() + padding,
+ code->relocation_info()->GetDataStartAddress(),
+ reloc_length);
+ // Create a relocation writer to write the comments in the padding
+ // space. Use position 0 for everything to ensure short encoding.
+ RelocInfoWriter reloc_info_writer(
+ new_reloc->GetDataStartAddress() + padding, 0);
+ intptr_t comment_string
+ = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString);
+ RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string);
+ for (int i = 0; i < additional_comments; ++i) {
+#ifdef DEBUG
+ byte* pos_before = reloc_info_writer.pos();
+#endif
+ reloc_info_writer.Write(&rinfo);
+ ASSERT(RelocInfo::kMinRelocCommentSize ==
+ pos_before - reloc_info_writer.pos());
+ }
+ // Replace relocation information on the code object.
+ code->set_relocation_info(*new_reloc);
+ }
+}
+
+
+void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
if (!function->IsOptimized()) return;
+ Isolate* isolate = function->GetIsolate();
+ HandleScope scope(isolate);
+ AssertNoAllocation no_allocation;
+
// Get the optimized code.
Code* code = function->code();
Address code_start_address = code->instruction_start();
@@ -119,11 +196,12 @@
// a non-live object in the extra space at the end of the former reloc info.
Address junk_address = reloc_info->address() + reloc_info->Size();
ASSERT(junk_address <= reloc_end_address);
- HEAP->CreateFillerObjectAt(junk_address, reloc_end_address - junk_address);
+ isolate->heap()->CreateFillerObjectAt(junk_address,
+ reloc_end_address - junk_address);
// Add the deoptimizing code to the list.
DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
- DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
+ DeoptimizerData* data = isolate->deoptimizer_data();
node->set_next(data->deoptimizing_code_list_);
data->deoptimizing_code_list_ = node;
@@ -325,7 +403,7 @@
output_[0]->SetPc(pc);
}
Code* continuation =
- Isolate::Current()->builtins()->builtin(Builtins::NotifyOSR);
+ function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
output_[0]->SetContinuation(
reinterpret_cast<uint32_t>(continuation->entry()));
@@ -494,8 +572,8 @@
if (is_topmost) {
Builtins* builtins = isolate_->builtins();
Code* continuation = (bailout_type_ == EAGER)
- ? builtins->builtin(Builtins::NotifyDeoptimized)
- : builtins->builtin(Builtins::NotifyLazyDeoptimized);
+ ? builtins->builtin(Builtins::kNotifyDeoptimized)
+ : builtins->builtin(Builtins::kNotifyLazyDeoptimized);
output_frame->SetContinuation(
reinterpret_cast<uint32_t>(continuation->entry()));
}
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index cc2f849..d1c869a 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -1373,6 +1373,12 @@
get_modrm(*data, &mod, ®op, &rm);
AppendToBuffer("movsd %s,", NameOfXMMRegister(regop));
data += PrintRightXMMOperand(data);
+ } else if (b2 == 0x5A) {
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("cvtsd2ss %s,", NameOfXMMRegister(regop));
+ data += PrintRightXMMOperand(data);
} else {
const char* mnem = "?";
switch (b2) {
@@ -1422,25 +1428,39 @@
case 0xF3:
if (*(data+1) == 0x0F) {
- if (*(data+2) == 0x2C) {
+ byte b2 = *(data+2);
+ if (b2 == 0x11) {
+ AppendToBuffer("movss ");
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ data += PrintRightXMMOperand(data);
+ AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ } else if (b2 == 0x10) {
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("movss %s,", NameOfXMMRegister(regop));
+ data += PrintRightXMMOperand(data);
+ } else if (b2 == 0x2C) {
data += 3;
int mod, regop, rm;
get_modrm(*data, &mod, ®op, &rm);
AppendToBuffer("cvttss2si %s,", NameOfCPURegister(regop));
data += PrintRightXMMOperand(data);
- } else if (*(data+2) == 0x5A) {
+ } else if (b2 == 0x5A) {
data += 3;
int mod, regop, rm;
get_modrm(*data, &mod, ®op, &rm);
AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
data += PrintRightXMMOperand(data);
- } else if (*(data+2) == 0x6F) {
+ } else if (b2 == 0x6F) {
data += 3;
int mod, regop, rm;
get_modrm(*data, &mod, ®op, &rm);
AppendToBuffer("movdqu %s,", NameOfXMMRegister(regop));
data += PrintRightXMMOperand(data);
- } else if (*(data+2) == 0x7F) {
+ } else if (b2 == 0x7F) {
AppendToBuffer("movdqu ");
data += 3;
int mod, regop, rm;
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index b1c53d6..16c39c5 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -732,9 +732,9 @@
prop->key()->AsLiteral()->handle()->IsSmi());
__ Set(ecx, Immediate(prop->key()->AsLiteral()->handle()));
- Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
- ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
}
@@ -1102,8 +1102,7 @@
// load IC call.
__ mov(eax, GlobalObjectOperand());
__ mov(ecx, slot->var()->name());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
@@ -1186,8 +1185,8 @@
ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
slow));
__ mov(eax, Immediate(key_literal->handle()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic =
+ isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ jmp(done);
}
@@ -1210,8 +1209,7 @@
// object on the stack.
__ mov(eax, GlobalObjectOperand());
__ mov(ecx, var->name());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
context()->Plug(eax);
@@ -1274,8 +1272,7 @@
__ mov(eax, Immediate(key_literal->handle()));
// Do a keyed property load.
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Drop key and object left on the stack by IC.
@@ -1386,9 +1383,9 @@
VisitForAccumulatorValue(value);
__ mov(ecx, Immediate(key->handle()));
__ mov(edx, Operand(esp, 0));
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
@@ -1637,16 +1634,14 @@
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ mov(ecx, Immediate(key->handle()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
@@ -1787,9 +1782,9 @@
__ mov(edx, eax);
__ pop(eax); // Restore value.
__ mov(ecx, prop->key()->AsLiteral()->handle());
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
break;
}
@@ -1810,9 +1805,9 @@
__ pop(edx);
}
__ pop(eax); // Restore value.
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
break;
}
@@ -1836,9 +1831,9 @@
// ecx, and the global object on the stack.
__ mov(ecx, var->name());
__ mov(edx, GlobalObjectOperand());
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
} else if (op == Token::INIT_CONST) {
@@ -1939,9 +1934,9 @@
} else {
__ pop(edx);
}
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case.
@@ -1979,9 +1974,9 @@
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case.
@@ -2102,7 +2097,7 @@
if (arg_count > 0) {
__ push(Operand(esp, arg_count * kPointerSize));
} else {
- __ push(Immediate(FACTORY->undefined_value()));
+ __ push(Immediate(isolate()->factory()->undefined_value()));
}
// Push the receiver of the enclosing function.
@@ -2257,8 +2252,7 @@
// Record source code position for IC call.
SetSourcePosition(prop->position());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Push result (function).
__ push(eax);
@@ -2326,8 +2320,8 @@
__ Set(eax, Immediate(arg_count));
__ mov(edi, Operand(esp, arg_count * kPointerSize));
- Handle<Code> construct_builtin(isolate()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Handle<Code> construct_builtin =
+ isolate()->builtins()->JSConstructCall();
__ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
context()->Plug(eax);
}
@@ -2806,8 +2800,12 @@
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- MathPowStub stub;
- __ CallStub(&stub);
+ if (isolate()->cpu_features()->IsSupported(SSE2)) {
+ MathPowStub stub;
+ __ CallStub(&stub);
+ } else {
+ __ CallRuntime(Runtime::kMath_pow, 2);
+ }
context()->Plug(eax);
}
@@ -3309,7 +3307,7 @@
__ mov(array_length, FieldOperand(array, JSArray::kLengthOffset));
__ SmiUntag(array_length);
__ j(not_zero, &non_trivial_array);
- __ mov(result_operand, FACTORY->empty_string());
+ __ mov(result_operand, isolate()->factory()->empty_string());
__ jmp(&done);
// Save the array length.
@@ -3520,7 +3518,7 @@
__ bind(&bailout);
- __ mov(result_operand, FACTORY->undefined_value());
+ __ mov(result_operand, isolate()->factory()->undefined_value());
__ bind(&done);
__ mov(eax, result_operand);
// Drop temp values from the stack, and restore context register.
@@ -3873,9 +3871,9 @@
case NAMED_PROPERTY: {
__ mov(ecx, prop->key()->AsLiteral()->handle());
__ pop(edx);
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -3890,9 +3888,9 @@
case KEYED_PROPERTY: {
__ pop(ecx);
__ pop(edx);
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -3918,8 +3916,7 @@
Comment cmnt(masm_, "Global variable");
__ mov(eax, GlobalObjectOperand());
__ mov(ecx, Immediate(proxy->name()));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
// Use a regular load, not a contextual load, to avoid a reference
// error.
EmitCallIC(ic, RelocInfo::CODE_TARGET);
@@ -4227,18 +4224,19 @@
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
+ Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
- __ IncrementCounter(COUNTERS->named_load_full(), 1);
+ __ IncrementCounter(counters->named_load_full(), 1);
break;
case Code::KEYED_LOAD_IC:
- __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
+ __ IncrementCounter(counters->keyed_load_full(), 1);
break;
case Code::STORE_IC:
- __ IncrementCounter(COUNTERS->named_store_full(), 1);
+ __ IncrementCounter(counters->named_store_full(), 1);
break;
case Code::KEYED_STORE_IC:
- __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
+ __ IncrementCounter(counters->keyed_store_full(), 1);
default:
break;
}
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index f2558bf..48ffc73 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -555,7 +555,9 @@
eax,
NULL,
&slow);
- __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1);
+ Isolate* isolate = masm->isolate();
+ Counters* counters = isolate->counters();
+ __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
__ ret(0);
__ bind(&check_number_dictionary);
@@ -568,7 +570,7 @@
// ebx: untagged index
// eax: key
// ecx: elements
- __ CheckMap(ecx, FACTORY->hash_table_map(), &slow, true);
+ __ CheckMap(ecx, isolate->factory()->hash_table_map(), &slow, true);
Label slow_pop_receiver;
// Push receiver on the stack to free up a register for the dictionary
// probing.
@@ -593,7 +595,7 @@
// Slow case: jump to runtime.
// edx: receiver
// eax: key
- __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
GenerateRuntimeGetProperty(masm);
__ bind(&check_string);
@@ -606,7 +608,7 @@
// cache. Otherwise probe the dictionary.
__ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
__ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
- Immediate(FACTORY->hash_table_map()));
+ Immediate(isolate->factory()->hash_table_map()));
__ j(equal, &probe_dictionary);
// Load the map of the receiver, compute the keyed lookup cache hash
@@ -648,7 +650,7 @@
__ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
__ add(ecx, Operand(edi));
__ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
- __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
__ ret(0);
// Load property array property.
@@ -656,7 +658,7 @@
__ mov(eax, FieldOperand(edx, JSObject::kPropertiesOffset));
__ mov(eax, FieldOperand(eax, edi, times_pointer_size,
FixedArray::kHeaderSize));
- __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
__ ret(0);
// Do a quick inline probe of the receiver's dictionary, if it
@@ -668,7 +670,7 @@
GenerateGlobalInstanceTypeCheck(masm, ecx, &slow);
GenerateDictionaryLoad(masm, &slow, ebx, eax, ecx, edi, eax);
- __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
__ ret(0);
__ bind(&index_string);
@@ -967,10 +969,11 @@
// -- esp[(argc + 1) * 4] : receiver
// -----------------------------------
+ Counters* counters = masm->isolate()->counters();
if (id == IC::kCallIC_Miss) {
- __ IncrementCounter(COUNTERS->call_miss(), 1);
+ __ IncrementCounter(counters->call_miss(), 1);
} else {
- __ IncrementCounter(COUNTERS->keyed_call_miss(), 1);
+ __ IncrementCounter(counters->keyed_call_miss(), 1);
}
// Get the receiver of the function from the stack; 1 ~ return address.
@@ -1092,7 +1095,9 @@
GenerateFastArrayLoad(
masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load);
- __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1);
+ Isolate* isolate = masm->isolate();
+ Counters* counters = isolate->counters();
+ __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1);
__ bind(&do_call);
// receiver in edx is not used after this point.
@@ -1104,14 +1109,14 @@
// eax: elements
// ecx: smi key
// Check whether the elements is a number dictionary.
- __ CheckMap(eax, FACTORY->hash_table_map(), &slow_load, true);
+ __ CheckMap(eax, isolate->factory()->hash_table_map(), &slow_load, true);
__ mov(ebx, ecx);
__ SmiUntag(ebx);
// ebx: untagged index
// Receiver in edx will be clobbered, need to reload it on miss.
GenerateNumberDictionaryLoad(
masm, &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi);
- __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
__ jmp(&do_call);
__ bind(&slow_reload_receiver);
@@ -1120,7 +1125,7 @@
__ bind(&slow_load);
// This branch is taken when calling KeyedCallIC_Miss is neither required
// nor beneficial.
- __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
__ EnterInternalFrame();
__ push(ecx); // save the key
__ push(edx); // pass the receiver
@@ -1142,14 +1147,17 @@
masm, edx, eax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache);
__ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
- __ CheckMap(ebx, FACTORY->hash_table_map(), &lookup_monomorphic_cache, true);
+ __ CheckMap(ebx,
+ isolate->factory()->hash_table_map(),
+ &lookup_monomorphic_cache,
+ true);
GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi);
- __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
__ jmp(&do_call);
__ bind(&lookup_monomorphic_cache);
- __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
// Fall through on miss.
@@ -1160,7 +1168,7 @@
// - the value loaded is not a function,
// - there is hope that the runtime will create a monomorphic call stub
// that will get fetched next time.
- __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
GenerateMiss(masm, argc);
__ bind(&index_string);
@@ -1251,7 +1259,7 @@
// -- esp[0] : return address
// -----------------------------------
- __ IncrementCounter(COUNTERS->load_miss(), 1);
+ __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
__ pop(ebx);
__ push(eax); // receiver
@@ -1438,7 +1446,7 @@
// -- esp[0] : return address
// -----------------------------------
- __ IncrementCounter(COUNTERS->keyed_load_miss(), 1);
+ __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1);
__ pop(ebx);
__ push(edx); // receiver
@@ -1589,14 +1597,15 @@
__ push(edx);
GenerateDictionaryStore(masm, &restore_miss, ebx, ecx, eax, edx, edi);
__ Drop(1);
- __ IncrementCounter(COUNTERS->store_normal_hit(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->store_normal_hit(), 1);
__ ret(0);
__ bind(&restore_miss);
__ pop(edx);
__ bind(&miss);
- __ IncrementCounter(COUNTERS->store_normal_miss(), 1);
+ __ IncrementCounter(counters->store_normal_miss(), 1);
GenerateMiss(masm);
}
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index ef30b68..fff754b 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -31,6 +31,7 @@
#include "ia32/lithium-codegen-ia32.h"
#include "code-stubs.h"
+#include "deoptimizer.h"
#include "stub-cache.h"
namespace v8 {
@@ -43,20 +44,13 @@
public:
SafepointGenerator(LCodeGen* codegen,
LPointerMap* pointers,
- int deoptimization_index,
- bool ensure_reloc_space = false)
+ int deoptimization_index)
: codegen_(codegen),
pointers_(pointers),
- deoptimization_index_(deoptimization_index),
- ensure_reloc_space_(ensure_reloc_space) { }
+ deoptimization_index_(deoptimization_index) {}
virtual ~SafepointGenerator() { }
virtual void Generate() {
- // Ensure that we have enough space in the reloc info to patch
- // this with calls when doing deoptimization.
- if (ensure_reloc_space_) {
- codegen_->EnsureRelocSpaceForDeoptimization();
- }
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
}
@@ -64,7 +58,6 @@
LCodeGen* codegen_;
LPointerMap* pointers_;
int deoptimization_index_;
- bool ensure_reloc_space_;
};
@@ -78,7 +71,6 @@
return GeneratePrologue() &&
GenerateBody() &&
GenerateDeferredCode() &&
- GenerateRelocPadding() &&
GenerateSafepointTable();
}
@@ -88,6 +80,7 @@
code->set_stack_slots(StackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
PopulateDeoptimizationData(code);
+ Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
}
@@ -385,22 +378,6 @@
}
-void LCodeGen::EnsureRelocSpaceForDeoptimization() {
- // Since we patch the reloc info with RUNTIME_ENTRY calls every patch
- // site will take up 2 bytes + any pc-jumps.
- // We are conservative and always reserver 6 bytes in case where a
- // simple pc-jump is not enough.
- uint32_t pc_delta =
- masm()->pc_offset() - deoptimization_reloc_size.last_pc_offset;
- if (is_uintn(pc_delta, 6)) {
- deoptimization_reloc_size.min_size += 2;
- } else {
- deoptimization_reloc_size.min_size += 6;
- }
- deoptimization_reloc_size.last_pc_offset = masm()->pc_offset();
-}
-
-
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged) {
@@ -454,7 +431,6 @@
}
__ call(code, mode);
- EnsureRelocSpaceForDeoptimization();
RegisterLazyDeoptimization(instr);
// Signal that we don't inline smi code before these stubs in the
@@ -479,6 +455,7 @@
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
}
__ CallRuntime(fun, argc);
+
RegisterLazyDeoptimization(instr);
}
@@ -2113,7 +2090,7 @@
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
- Register object = ToRegister(instr->InputAt(0));
+ Register object = ToRegister(instr->object());
Register result = ToRegister(instr->result());
if (instr->hydrogen()->is_in_object()) {
__ mov(result, FieldOperand(object, instr->hydrogen()->offset()));
@@ -2124,13 +2101,76 @@
}
+void LCodeGen::EmitLoadField(Register result,
+ Register object,
+ Handle<Map> type,
+ Handle<String> name) {
+ LookupResult lookup;
+ type->LookupInDescriptors(NULL, *name, &lookup);
+ ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
+ int index = lookup.GetLocalFieldIndexFromMap(*type);
+ int offset = index * kPointerSize;
+ if (index < 0) {
+ // Negative property indices are in-object properties, indexed
+ // from the end of the fixed part of the object.
+ __ mov(result, FieldOperand(object, offset + type->instance_size()));
+ } else {
+ // Non-negative property indices are in the properties array.
+ __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
+ __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
+ }
+}
+
+
+void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
+ Register object = ToRegister(instr->object());
+ Register result = ToRegister(instr->result());
+
+ int map_count = instr->hydrogen()->types()->length();
+ Handle<String> name = instr->hydrogen()->name();
+ if (map_count == 0) {
+ ASSERT(instr->hydrogen()->need_generic());
+ __ mov(ecx, name);
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, false);
+ } else {
+ NearLabel done;
+ for (int i = 0; i < map_count - 1; ++i) {
+ Handle<Map> map = instr->hydrogen()->types()->at(i);
+ NearLabel next;
+ __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+ __ j(not_equal, &next);
+ EmitLoadField(result, object, map, name);
+ __ jmp(&done);
+ __ bind(&next);
+ }
+ Handle<Map> map = instr->hydrogen()->types()->last();
+ __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+ if (instr->hydrogen()->need_generic()) {
+ NearLabel generic;
+ __ j(not_equal, &generic);
+ EmitLoadField(result, object, map, name);
+ __ jmp(&done);
+ __ bind(&generic);
+ __ mov(ecx, name);
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ CallCode(ic, RelocInfo::CODE_TARGET, instr, false);
+ } else {
+ DeoptimizeIf(not_equal, instr->environment());
+ EmitLoadField(result, object, map, name);
+ }
+ __ bind(&done);
+ }
+}
+
+
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
ASSERT(ToRegister(instr->object()).is(eax));
ASSERT(ToRegister(instr->result()).is(eax));
__ mov(ecx, instr->name());
- Handle<Code> ic(isolate()->builtins()->builtin(Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2187,11 +2227,16 @@
Immediate(factory()->fixed_array_map()));
__ j(equal, &done);
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(factory()->external_pixel_array_map()));
- __ j(equal, &done);
- __ cmp(FieldOperand(result, HeapObject::kMapOffset),
Immediate(factory()->fixed_cow_array_map()));
- __ Check(equal, "Check for fast elements or pixel array failed.");
+ __ j(equal, &done);
+ Register temp((result.is(eax)) ? ebx : eax);
+ __ push(temp);
+ __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
+ __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
+ __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
+ __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount));
+ __ pop(temp);
+ __ Check(below, "Check for fast elements or pixel array failed.");
__ bind(&done);
}
}
@@ -2239,14 +2284,47 @@
}
-void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
+void LCodeGen::DoLoadKeyedSpecializedArrayElement(
+ LLoadKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
- Register result = ToRegister(instr->result());
- ASSERT(result.is(external_pointer));
-
- // Load the result.
- __ movzx_b(result, Operand(external_pointer, key, times_1, 0));
+ ExternalArrayType array_type = instr->array_type();
+ if (array_type == kExternalFloatArray) {
+ XMMRegister result(ToDoubleRegister(instr->result()));
+ __ movss(result, Operand(external_pointer, key, times_4, 0));
+ __ cvtss2sd(result, result);
+ } else {
+ Register result(ToRegister(instr->result()));
+ switch (array_type) {
+ case kExternalByteArray:
+ __ movsx_b(result, Operand(external_pointer, key, times_1, 0));
+ break;
+ case kExternalUnsignedByteArray:
+ case kExternalPixelArray:
+ __ movzx_b(result, Operand(external_pointer, key, times_1, 0));
+ break;
+ case kExternalShortArray:
+ __ movsx_w(result, Operand(external_pointer, key, times_2, 0));
+ break;
+ case kExternalUnsignedShortArray:
+ __ movzx_w(result, Operand(external_pointer, key, times_2, 0));
+ break;
+ case kExternalIntArray:
+ __ mov(result, Operand(external_pointer, key, times_4, 0));
+ break;
+ case kExternalUnsignedIntArray:
+ __ mov(result, Operand(external_pointer, key, times_4, 0));
+ __ test(Operand(result), Immediate(0x80000000));
+ // TODO(danno): we could be more clever here, perhaps having a special
+ // version of the stub that detects if the overflow case actually
+ // happens, and generate code that returns a double rather than int.
+ DeoptimizeIf(not_zero, instr->environment());
+ break;
+ case kExternalFloatArray:
+ UNREACHABLE();
+ break;
+ }
+ }
}
@@ -2255,8 +2333,7 @@
ASSERT(ToRegister(instr->object()).is(edx));
ASSERT(ToRegister(instr->key()).is(eax));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2370,8 +2447,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator safepoint_generator(this,
pointers,
- env->deoptimization_index(),
- true);
+ env->deoptimization_index());
v8::internal::ParameterCount actual(eax);
__ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
}
@@ -2443,7 +2519,6 @@
__ CallSelf();
} else {
__ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
- EnsureRelocSpaceForDeoptimization();
}
// Setup deoptimization.
@@ -2813,8 +2888,7 @@
ASSERT(ToRegister(instr->constructor()).is(edi));
ASSERT(ToRegister(instr->result()).is(eax));
- Handle<Code> builtin(isolate()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
__ Set(eax, Immediate(instr->arity()));
CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -2861,9 +2935,9 @@
ASSERT(ToRegister(instr->value()).is(eax));
__ mov(ecx, instr->name());
- Handle<Code> ic(isolate()->builtins()->builtin(
- info_->is_strict() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = info_->is_strict()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2874,22 +2948,52 @@
}
-void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) {
+void LCodeGen::DoStoreKeyedSpecializedArrayElement(
+ LStoreKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
- Register value = ToRegister(instr->value());
- ASSERT(ToRegister(instr->TempAt(0)).is(eax));
-
- __ mov(eax, value);
- { // Clamp the value to [0..255].
- NearLabel done;
- __ test(eax, Immediate(0xFFFFFF00));
- __ j(zero, &done);
- __ setcc(negative, eax); // 1 if negative, 0 if positive.
- __ dec_b(eax); // 0 if negative, 255 if positive.
- __ bind(&done);
+ ExternalArrayType array_type = instr->array_type();
+ if (array_type == kExternalFloatArray) {
+ __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
+ __ movss(Operand(external_pointer, key, times_4, 0), xmm0);
+ } else {
+ Register value = ToRegister(instr->value());
+ switch (array_type) {
+ case kExternalPixelArray: {
+ // Clamp the value to [0..255].
+ Register temp = ToRegister(instr->TempAt(0));
+ // The dec_b below requires that the clamped value is in a byte
+ // register. eax is an arbitrary choice to satisfy this requirement, we
+ // hinted the register allocator to give us eax when building the
+ // instruction.
+ ASSERT(temp.is(eax));
+ __ mov(temp, ToRegister(instr->value()));
+ NearLabel done;
+ __ test(temp, Immediate(0xFFFFFF00));
+ __ j(zero, &done);
+ __ setcc(negative, temp); // 1 if negative, 0 if positive.
+ __ dec_b(temp); // 0 if negative, 255 if positive.
+ __ bind(&done);
+ __ mov_b(Operand(external_pointer, key, times_1, 0), temp);
+ break;
+ }
+ case kExternalByteArray:
+ case kExternalUnsignedByteArray:
+ __ mov_b(Operand(external_pointer, key, times_1, 0), value);
+ break;
+ case kExternalShortArray:
+ case kExternalUnsignedShortArray:
+ __ mov_w(Operand(external_pointer, key, times_2, 0), value);
+ break;
+ case kExternalIntArray:
+ case kExternalUnsignedIntArray:
+ __ mov(Operand(external_pointer, key, times_4, 0), value);
+ break;
+ case kExternalFloatArray:
+ UNREACHABLE();
+ break;
+ }
}
- __ mov_b(Operand(external_pointer, key, times_1, 0), eax);
}
@@ -2931,9 +3035,9 @@
ASSERT(ToRegister(instr->key()).is(ecx));
ASSERT(ToRegister(instr->value()).is(eax));
- Handle<Code> ic(isolate()->builtins()->builtin(
- info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = info_->is_strict()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -3973,8 +4077,7 @@
// builtin)
SafepointGenerator safepoint_generator(this,
pointers,
- env->deoptimization_index(),
- true);
+ env->deoptimization_index());
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
__ push(Immediate(Smi::FromInt(strict_mode_flag())));
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index d06603c..4414e6a 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -246,6 +246,10 @@
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp);
+ void EmitLoadField(Register result,
+ Register object,
+ Handle<Map> type,
+ Handle<String> name);
LChunk* const chunk_;
MacroAssembler* const masm_;
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 96b7937..d23ccdc 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1790,6 +1790,21 @@
}
+LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
+ HLoadNamedFieldPolymorphic* instr) {
+ ASSERT(instr->representation().IsTagged());
+ if (instr->need_generic()) {
+ LOperand* obj = UseFixed(instr->object(), eax);
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+ return MarkAsCall(DefineFixed(result, eax), instr);
+ } else {
+ LOperand* obj = UseRegisterAtStart(instr->object());
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+ return AssignEnvironment(DefineAsRegister(result));
+ }
+}
+
+
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi);
LOperand* object = UseFixed(instr->object(), eax);
@@ -1830,16 +1845,24 @@
}
-LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
- HLoadPixelArrayElement* instr) {
- ASSERT(instr->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
+ HLoadKeyedSpecializedArrayElement* instr) {
+ ExternalArrayType array_type = instr->array_type();
+ Representation representation(instr->representation());
+ ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+ (representation.IsDouble() && array_type == kExternalFloatArray));
ASSERT(instr->key()->representation().IsInteger32());
- LOperand* external_pointer =
- UseRegisterAtStart(instr->external_pointer());
- LOperand* key = UseRegisterAtStart(instr->key());
- LLoadPixelArrayElement* result =
- new LLoadPixelArrayElement(external_pointer, key);
- return DefineSameAsFirst(result);
+ LOperand* external_pointer = UseRegister(instr->external_pointer());
+ LOperand* key = UseRegister(instr->key());
+ LLoadKeyedSpecializedArrayElement* result =
+ new LLoadKeyedSpecializedArrayElement(external_pointer,
+ key);
+ LInstruction* load_instr = DefineAsRegister(result);
+ // An unsigned int array load might overflow and cause a deopt, make sure it
+ // has an environment.
+ return (array_type == kExternalUnsignedIntArray)
+ ? AssignEnvironment(load_instr)
+ : load_instr;
}
@@ -1872,20 +1895,31 @@
}
-LInstruction* LChunkBuilder::DoStorePixelArrayElement(
- HStorePixelArrayElement* instr) {
- ASSERT(instr->value()->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
+ HStoreKeyedSpecializedArrayElement* instr) {
+ Representation representation(instr->value()->representation());
+ ExternalArrayType array_type = instr->array_type();
+ ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+ (representation.IsDouble() && array_type == kExternalFloatArray));
ASSERT(instr->external_pointer()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* val = UseRegister(instr->value());
LOperand* key = UseRegister(instr->key());
- // The generated code requires that the clamped value is in a byte
- // register. eax is an arbitrary choice to satisfy this requirement.
- LOperand* clamped = FixedTemp(eax);
+ LOperand* temp = NULL;
- return new LStorePixelArrayElement(external_pointer, key, val, clamped);
+ if (array_type == kExternalPixelArray) {
+ // The generated code for pixel array stores requires that the clamped value
+ // is in a byte register. eax is an arbitrary choice to satisfy this
+ // requirement.
+ temp = FixedTemp(eax);
+ }
+
+ return new LStoreKeyedSpecializedArrayElement(external_pointer,
+ key,
+ val,
+ temp);
}
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 70ec962..a9d769b 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -124,9 +124,10 @@
V(LoadGlobal) \
V(LoadKeyedFastElement) \
V(LoadKeyedGeneric) \
+ V(LoadKeyedSpecializedArrayElement) \
V(LoadNamedField) \
+ V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
- V(LoadPixelArrayElement) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@@ -148,9 +149,9 @@
V(StoreGlobal) \
V(StoreKeyedFastElement) \
V(StoreKeyedGeneric) \
+ V(StoreKeyedSpecializedArrayElement) \
V(StoreNamedField) \
V(StoreNamedGeneric) \
- V(StorePixelArrayElement) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
V(StringLength) \
@@ -1171,6 +1172,21 @@
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
+
+ LOperand* object() { return inputs_[0]; }
+};
+
+
+class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LLoadNamedFieldPolymorphic(LOperand* object) {
+ inputs_[0] = object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
+ DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
+
+ LOperand* object() { return inputs_[0]; }
};
@@ -1240,19 +1256,23 @@
};
-class LLoadPixelArrayElement: public LTemplateInstruction<1, 2, 0> {
+class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
public:
- LLoadPixelArrayElement(LOperand* external_pointer, LOperand* key) {
+ LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
+ LOperand* key) {
inputs_[0] = external_pointer;
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
- "load-pixel-array-element")
- DECLARE_HYDROGEN_ACCESSOR(LoadPixelArrayElement)
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+ "load-keyed-specialized-array-element")
+ DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+ ExternalArrayType array_type() const {
+ return hydrogen()->array_type();
+ }
};
@@ -1658,25 +1678,28 @@
};
-class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 1> {
+class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 1> {
public:
- LStorePixelArrayElement(LOperand* external_pointer,
- LOperand* key,
- LOperand* val,
- LOperand* clamped) {
+ LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
+ LOperand* key,
+ LOperand* val,
+ LOperand* temp) {
inputs_[0] = external_pointer;
inputs_[1] = key;
inputs_[2] = val;
- temps_[0] = clamped;
+ temps_[0] = temp;
}
- DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
- "store-pixel-array-element")
- DECLARE_HYDROGEN_ACCESSOR(StorePixelArrayElement)
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+ "store-keyed-specialized-array-element")
+ DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+ ExternalArrayType array_type() const {
+ return hydrogen()->array_type();
+ }
};
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 950cf31..ba30c49 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -45,7 +45,7 @@
: Assembler(buffer, size),
generating_stub_(false),
allow_stub_calls_(true),
- code_object_(HEAP->undefined_value()) {
+ code_object_(isolate()->heap()->undefined_value()) {
}
@@ -250,7 +250,7 @@
test(object, Immediate(kSmiTagMask));
j(zero, &ok);
cmp(FieldOperand(object, HeapObject::kMapOffset),
- FACTORY->heap_number_map());
+ isolate()->factory()->heap_number_map());
Assert(equal, "Operand not a number");
bind(&ok);
}
@@ -286,7 +286,7 @@
push(Immediate(Smi::FromInt(type)));
push(Immediate(CodeObject()));
if (emit_debug_code()) {
- cmp(Operand(esp, 0), Immediate(FACTORY->undefined_value()));
+ cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value()));
Check(not_equal, "code object not properly patched");
}
}
@@ -577,7 +577,7 @@
push(scratch);
// Read the first word and compare to global_context_map.
mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
- cmp(scratch, FACTORY->global_context_map());
+ cmp(scratch, isolate()->factory()->global_context_map());
Check(equal, "JSGlobalObject::global_context should be a global context.");
pop(scratch);
}
@@ -598,13 +598,13 @@
// Check the context is a global context.
if (emit_debug_code()) {
- cmp(holder_reg, FACTORY->null_value());
+ cmp(holder_reg, isolate()->factory()->null_value());
Check(not_equal, "JSGlobalProxy::context() should not be null.");
push(holder_reg);
// Read the first word and compare to global_context_map(),
mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
- cmp(holder_reg, FACTORY->global_context_map());
+ cmp(holder_reg, isolate()->factory()->global_context_map());
Check(equal, "JSGlobalObject::global_context should be a global context.");
pop(holder_reg);
}
@@ -843,7 +843,7 @@
// Set the map.
mov(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(FACTORY->heap_number_map()));
+ Immediate(isolate()->factory()->heap_number_map()));
}
@@ -873,7 +873,7 @@
// Set the map, length and hash field.
mov(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(FACTORY->string_map()));
+ Immediate(isolate()->factory()->string_map()));
mov(scratch1, length);
SmiTag(scratch1);
mov(FieldOperand(result, String::kLengthOffset), scratch1);
@@ -908,7 +908,7 @@
// Set the map, length and hash field.
mov(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(FACTORY->ascii_string_map()));
+ Immediate(isolate()->factory()->ascii_string_map()));
mov(scratch1, length);
SmiTag(scratch1);
mov(FieldOperand(result, String::kLengthOffset), scratch1);
@@ -934,7 +934,7 @@
// Set the map, length and hash field.
mov(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(FACTORY->ascii_string_map()));
+ Immediate(isolate()->factory()->ascii_string_map()));
mov(FieldOperand(result, String::kLengthOffset),
Immediate(Smi::FromInt(length)));
mov(FieldOperand(result, String::kHashFieldOffset),
@@ -956,7 +956,7 @@
// Set the map. The other fields are left uninitialized.
mov(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(FACTORY->cons_string_map()));
+ Immediate(isolate()->factory()->cons_string_map()));
}
@@ -974,7 +974,7 @@
// Set the map. The other fields are left uninitialized.
mov(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(FACTORY->cons_ascii_string_map()));
+ Immediate(isolate()->factory()->cons_ascii_string_map()));
}
@@ -1092,7 +1092,7 @@
// If the prototype or initial map is the hole, don't return it and
// simply miss the cache instead. This will allow us to allocate a
// prototype object on-demand in the runtime system.
- cmp(Operand(result), Immediate(FACTORY->the_hole_value()));
+ cmp(Operand(result), Immediate(isolate()->factory()->the_hole_value()));
j(equal, miss, not_taken);
// If the function does not have an initial map, we're done.
@@ -1158,7 +1158,7 @@
if (num_arguments > 0) {
add(Operand(esp), Immediate(num_arguments * kPointerSize));
}
- mov(eax, Immediate(FACTORY->undefined_value()));
+ mov(eax, Immediate(isolate()->factory()->undefined_value()));
}
@@ -1229,7 +1229,7 @@
IllegalOperation(num_arguments);
// Since we did not call the stub, there was no allocation failure.
// Return some non-failure object.
- return HEAP->undefined_value();
+ return isolate()->heap()->undefined_value();
}
// TODO(1236192): Most runtime routines don't need the number of
@@ -1403,7 +1403,7 @@
}
bind(&empty_handle);
// It was zero; the result is undefined.
- mov(eax, FACTORY->undefined_value());
+ mov(eax, isolate()->factory()->undefined_value());
jmp(&prologue);
// HandleScope limit has changed. Delete allocated extensions.
@@ -1486,8 +1486,7 @@
if (!definitely_matches) {
Handle<Code> adaptor =
- Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::ArgumentsAdaptorTrampoline));
+ isolate()->builtins()->ArgumentsAdaptorTrampoline();
if (!code_constant.is_null()) {
mov(edx, Immediate(code_constant));
add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag));
@@ -1665,7 +1664,7 @@
mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
if (emit_debug_code()) {
Label ok, fail;
- CheckMap(map, FACTORY->meta_map(), &fail, false);
+ CheckMap(map, isolate()->factory()->meta_map(), &fail, false);
jmp(&ok);
bind(&fail);
Abort("Global functions must have initial map");
@@ -1813,12 +1812,13 @@
void MacroAssembler::AssertFastElements(Register elements) {
if (emit_debug_code()) {
+ Factory* factory = isolate()->factory();
Label ok;
cmp(FieldOperand(elements, HeapObject::kMapOffset),
- Immediate(FACTORY->fixed_array_map()));
+ Immediate(factory->fixed_array_map()));
j(equal, &ok);
cmp(FieldOperand(elements, HeapObject::kMapOffset),
- Immediate(FACTORY->fixed_cow_array_map()));
+ Immediate(factory->fixed_cow_array_map()));
j(equal, &ok);
Abort("JSObject with fast elements map has slow elements");
bind(&ok);
@@ -1883,7 +1883,7 @@
if (emit_debug_code()) AbortIfSmi(reg);
if (!info.IsNumber()) {
cmp(FieldOperand(reg, HeapObject::kMapOffset),
- FACTORY->heap_number_map());
+ isolate()->factory()->heap_number_map());
j(not_equal, on_not_number);
}
}
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index a5243a8..bb8d2d3 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -114,8 +114,9 @@
Register r0,
Register r1) {
ASSERT(name->IsSymbol());
- __ IncrementCounter(COUNTERS->negative_lookups(), 1);
- __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->negative_lookups(), 1);
+ __ IncrementCounter(counters->negative_lookups_miss(), 1);
Label done;
__ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
@@ -198,7 +199,7 @@
}
__ bind(&done);
- __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1);
+ __ DecrementCounter(counters->negative_lookups_miss(), 1);
}
@@ -276,11 +277,11 @@
MacroAssembler* masm, int index, Register prototype, Label* miss) {
// Check we're still in the same context.
__ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
- Isolate::Current()->global());
+ masm->isolate()->global());
__ j(not_equal, miss);
// Get the global function with the given index.
- JSFunction* function = JSFunction::cast(
- Isolate::Current()->global_context()->get(index));
+ JSFunction* function =
+ JSFunction::cast(masm->isolate()->global_context()->get(index));
// Load its initial map. The global functions all have initial maps.
__ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
// Load the prototype from the initial map.
@@ -398,7 +399,7 @@
JSObject* holder_obj) {
__ push(name);
InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
- ASSERT(!HEAP->InNewSpace(interceptor));
+ ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor));
Register scratch = name;
__ mov(scratch, Immediate(Handle<Object>(interceptor)));
__ push(scratch);
@@ -484,7 +485,7 @@
__ mov(Operand(esp, 2 * kPointerSize), edi);
Object* call_data = optimization.api_call_info()->data();
Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
- if (HEAP->InNewSpace(call_data)) {
+ if (masm->isolate()->heap()->InNewSpace(call_data)) {
__ mov(ecx, api_call_info_handle);
__ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
__ mov(Operand(esp, 3 * kPointerSize), ebx);
@@ -578,7 +579,7 @@
name,
holder,
miss);
- return HEAP->undefined_value(); // Success.
+ return masm->isolate()->heap()->undefined_value(); // Success.
}
}
@@ -614,10 +615,11 @@
(depth2 != kInvalidProtoDepth);
}
- __ IncrementCounter(COUNTERS->call_const_interceptor(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->call_const_interceptor(), 1);
if (can_do_fast_api_call) {
- __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1);
+ __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1);
ReserveSpaceForFastApiCall(masm, scratch1);
}
@@ -676,7 +678,7 @@
FreeSpaceForFastApiCall(masm, scratch1);
}
- return HEAP->undefined_value(); // Success.
+ return masm->isolate()->heap()->undefined_value(); // Success.
}
void CompileRegular(MacroAssembler* masm,
@@ -746,9 +748,9 @@
ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
Code* code = NULL;
if (kind == Code::LOAD_IC) {
- code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss);
+ code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
} else {
- code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
+ code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
}
Handle<Code> ic(code);
@@ -913,6 +915,9 @@
ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
&& !scratch2.is(scratch1));
+
+ Heap* heap = isolate()->heap();
+
// Keep track of the current object in register reg.
Register reg = object_reg;
JSObject* current = object;
@@ -937,7 +942,7 @@
!current->IsJSGlobalObject() &&
!current->IsJSGlobalProxy()) {
if (!name->IsSymbol()) {
- MaybeObject* maybe_lookup_result = HEAP->LookupSymbol(name);
+ MaybeObject* maybe_lookup_result = heap->LookupSymbol(name);
Object* lookup_result = NULL; // Initialization to please compiler.
if (!maybe_lookup_result->ToObject(&lookup_result)) {
set_failure(Failure::cast(maybe_lookup_result));
@@ -957,7 +962,7 @@
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
reg = holder_reg; // from now the object is in holder_reg
__ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
- } else if (HEAP->InNewSpace(prototype)) {
+ } else if (heap->InNewSpace(prototype)) {
// Get the map of the current object.
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
__ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map())));
@@ -1087,7 +1092,7 @@
ASSERT(!scratch2.is(reg));
__ push(reg); // holder
// Push data from AccessorInfo.
- if (HEAP->InNewSpace(callback_handle->data())) {
+ if (isolate()->heap()->InNewSpace(callback_handle->data())) {
__ mov(scratch1, Immediate(callback_handle));
__ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));
} else {
@@ -1283,7 +1288,7 @@
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
- masm()->isolate());
+ isolate());
__ TailCallExternalReference(ref, 5, 1);
}
}
@@ -1334,7 +1339,7 @@
}
// Check that the cell contains the same function.
- if (HEAP->InNewSpace(function)) {
+ if (isolate()->heap()->InNewSpace(function)) {
// We can't embed a pointer to a function in new space so we have
// to verify that the shared function info is unchanged. This has
// the nice side effect that multiple closures based on the same
@@ -1358,8 +1363,8 @@
MaybeObject* CallStubCompiler::GenerateMissBranch() {
MaybeObject* maybe_obj =
- Isolate::Current()->stub_cache()->ComputeCallMiss(
- arguments().immediate(), kind_);
+ isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
+ kind_);
Object* obj;
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
__ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
@@ -1437,7 +1442,9 @@
// -----------------------------------
// If object is not an array, bail out to regular call.
- if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value();
+ if (!object->IsJSArray() || cell != NULL) {
+ return isolate()->heap()->undefined_value();
+ }
Label miss;
@@ -1515,11 +1522,10 @@
__ jmp(&call_builtin);
}
- Isolate* isolate = masm()->isolate();
ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
+ ExternalReference::new_space_allocation_top_address(isolate());
ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
+ ExternalReference::new_space_allocation_limit_address(isolate());
const int kAllocationDelta = 4;
// Load top.
@@ -1561,7 +1567,7 @@
__ bind(&call_builtin);
__ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, masm()->isolate()),
+ ExternalReference(Builtins::c_ArrayPush, isolate()),
argc + 1,
1);
}
@@ -1589,7 +1595,9 @@
// -----------------------------------
// If object is not an array, bail out to regular call.
- if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value();
+ if (!object->IsJSArray() || cell != NULL) {
+ return isolate()->heap()->undefined_value();
+ }
Label miss, return_undefined, call_builtin;
@@ -1644,7 +1652,7 @@
__ bind(&call_builtin);
__ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPop, masm()->isolate()),
+ ExternalReference(Builtins::c_ArrayPop, isolate()),
argc + 1,
1);
@@ -1673,7 +1681,7 @@
// If object is not a string, bail out to regular call.
if (!object->IsString() || cell != NULL) {
- return masm()->isolate()->heap()->undefined_value();
+ return isolate()->heap()->undefined_value();
}
const int argc = arguments().immediate();
@@ -1756,7 +1764,9 @@
// -----------------------------------
// If object is not a string, bail out to regular call.
- if (!object->IsString() || cell != NULL) return HEAP->undefined_value();
+ if (!object->IsString() || cell != NULL) {
+ return isolate()->heap()->undefined_value();
+ }
const int argc = arguments().immediate();
@@ -1843,7 +1853,9 @@
// If the object is not a JSObject or we got an unexpected number of
// arguments, bail out to the regular call.
- if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
+ if (!object->IsJSObject() || argc != 1) {
+ return isolate()->heap()->undefined_value();
+ }
Label miss;
GenerateNameCheck(name, &miss);
@@ -1911,15 +1923,19 @@
// -- esp[(argc + 1) * 4] : receiver
// -----------------------------------
- if (!Isolate::Current()->cpu_features()->IsSupported(SSE2))
- return HEAP->undefined_value();
+ if (isolate()->cpu_features()->IsSupported(SSE2)) {
+ return isolate()->heap()->undefined_value();
+ }
+
CpuFeatures::Scope use_sse2(SSE2);
const int argc = arguments().immediate();
// If the object is not a JSObject or we got an unexpected number of
// arguments, bail out to the regular call.
- if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
+ if (!object->IsJSObject() || argc != 1) {
+ return isolate()->heap()->undefined_value();
+ }
Label miss;
GenerateNameCheck(name, &miss);
@@ -2041,7 +2057,9 @@
// If the object is not a JSObject or we got an unexpected number of
// arguments, bail out to the regular call.
- if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
+ if (!object->IsJSObject() || argc != 1) {
+ return isolate()->heap()->undefined_value();
+ }
Label miss;
GenerateNameCheck(name, &miss);
@@ -2137,11 +2155,12 @@
ASSERT(optimization.is_simple_api_call());
// Bail out if object is a global object as we don't want to
// repatch it to global receiver.
- if (object->IsGlobalObject()) return HEAP->undefined_value();
- if (cell != NULL) return HEAP->undefined_value();
+ Heap* heap = isolate()->heap();
+ if (object->IsGlobalObject()) return heap->undefined_value();
+ if (cell != NULL) return heap->undefined_value();
int depth = optimization.GetPrototypeDepthOfExpectedType(
JSObject::cast(object), holder);
- if (depth == kInvalidProtoDepth) return HEAP->undefined_value();
+ if (depth == kInvalidProtoDepth) return heap->undefined_value();
Label miss, miss_before_stack_reserved;
@@ -2155,8 +2174,9 @@
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &miss_before_stack_reserved, not_taken);
- __ IncrementCounter(COUNTERS->call_const(), 1);
- __ IncrementCounter(COUNTERS->call_const_fast_api(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->call_const(), 1);
+ __ IncrementCounter(counters->call_const_fast_api(), 1);
// Allocate space for v8::Arguments implicit values. Must be initialized
// before calling any runtime function.
@@ -2230,7 +2250,7 @@
SharedFunctionInfo* function_info = function->shared();
switch (check) {
case RECEIVER_MAP_CHECK:
- __ IncrementCounter(COUNTERS->call_const(), 1);
+ __ IncrementCounter(isolate()->counters()->call_const(), 1);
// Check that the maps haven't changed.
CheckPrototypes(JSObject::cast(object), edx, holder,
@@ -2430,7 +2450,8 @@
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
- __ IncrementCounter(COUNTERS->call_global_inline(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->call_global_inline(), 1);
ASSERT(function->is_compiled());
ParameterCount expected(function->shared()->formal_parameter_count());
if (V8::UseCrankshaft()) {
@@ -2447,7 +2468,7 @@
// Handle call cache miss.
__ bind(&miss);
- __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1);
+ __ IncrementCounter(counters->call_global_inline_miss(), 1);
MaybeObject* maybe_result = GenerateMissBranch();
if (maybe_result->IsFailure()) return maybe_result;
@@ -2479,8 +2500,7 @@
// Handle store cache miss.
__ bind(&miss);
__ mov(ecx, Immediate(Handle<String>(name))); // restore name
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2525,14 +2545,13 @@
__ push(ebx); // restore return address
// Do tail-call to the runtime system.
- Isolate* isolate = masm()->isolate();
ExternalReference store_callback_property =
- ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate);
+ ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
__ TailCallExternalReference(store_callback_property, 4, 1);
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss));
+ Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2576,14 +2595,13 @@
__ push(ebx); // restore return address
// Do tail-call to the runtime system.
- Isolate* isolate = masm()->isolate();
ExternalReference store_ic_property =
- ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate);
+ ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
__ TailCallExternalReference(store_ic_property, 4, 1);
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss));
+ Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2626,14 +2644,14 @@
__ mov(cell_operand, eax);
// Return the value (register eax).
- __ IncrementCounter(COUNTERS->named_store_global_inline(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->named_store_global_inline(), 1);
__ ret(0);
// Handle store cache miss.
__ bind(&miss);
- __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
+ Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2653,7 +2671,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_store_field(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_store_field(), 1);
// Check that the name has not changed.
__ cmp(Operand(ecx), Immediate(Handle<String>(name)));
@@ -2669,9 +2688,8 @@
// Handle store cache miss.
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_store_field(), 1);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_Miss));
+ __ DecrementCounter(counters->keyed_store_field(), 1);
+ Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2728,8 +2746,7 @@
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(
- Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
+ Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2774,14 +2791,14 @@
// Return undefined if maps of the full prototype chain are still the
// same and no global property with this name contains a value.
- __ mov(eax, FACTORY->undefined_value());
+ __ mov(eax, isolate()->factory()->undefined_value());
__ ret(0);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
- return GetCode(NONEXISTENT, HEAP->empty_string());
+ return GetCode(NONEXISTENT, isolate()->heap()->empty_string());
}
@@ -2925,12 +2942,13 @@
__ Check(not_equal, "DontDelete cells can't contain the hole");
}
- __ IncrementCounter(COUNTERS->named_load_global_stub(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->named_load_global_stub(), 1);
__ mov(eax, ebx);
__ ret(0);
__ bind(&miss);
- __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1);
+ __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
@@ -2949,7 +2967,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_field(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_field(), 1);
// Check that the name has not changed.
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -2958,7 +2977,7 @@
GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_field(), 1);
+ __ DecrementCounter(counters->keyed_load_field(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -2978,7 +2997,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_callback(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_callback(), 1);
// Check that the name has not changed.
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -2993,7 +3013,7 @@
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_callback(), 1);
+ __ DecrementCounter(counters->keyed_load_callback(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -3012,7 +3032,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_constant_function(), 1);
// Check that the name has not changed.
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3021,7 +3042,7 @@
GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi,
value, name, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+ __ DecrementCounter(counters->keyed_load_constant_function(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -3039,7 +3060,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_interceptor(), 1);
// Check that the name has not changed.
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3058,7 +3080,7 @@
name,
&miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+ __ DecrementCounter(counters->keyed_load_interceptor(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -3074,7 +3096,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_array_length(), 1);
// Check that the name has not changed.
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3082,7 +3105,7 @@
GenerateLoadArrayLength(masm(), edx, ecx, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1);
+ __ DecrementCounter(counters->keyed_load_array_length(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -3098,7 +3121,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_string_length(), 1);
// Check that the name has not changed.
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3106,7 +3130,7 @@
GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1);
+ __ DecrementCounter(counters->keyed_load_string_length(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -3122,7 +3146,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
// Check that the name has not changed.
__ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3130,7 +3155,7 @@
GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+ __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -3270,7 +3295,7 @@
int arg_number = shared->GetThisPropertyAssignmentArgument(i);
__ mov(ebx, edi);
__ cmp(eax, arg_number);
- if (Isolate::Current()->cpu_features()->IsSupported(CMOV)) {
+ if (isolate()->cpu_features()->IsSupported(CMOV)) {
CpuFeatures::Scope use_cmov(CMOV);
__ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
} else {
@@ -3305,16 +3330,16 @@
__ pop(ecx);
__ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
__ push(ecx);
- __ IncrementCounter(COUNTERS->constructed_objects(), 1);
- __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->constructed_objects(), 1);
+ __ IncrementCounter(counters->constructed_objects_stub(), 1);
__ ret(0);
// Jump to the generic stub in case the specialized code cannot handle the
// construction.
__ bind(&generic_stub_call);
- Code* code = Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructStubGeneric);
- Handle<Code> generic_construct_stub(code);
+ Handle<Code> generic_construct_stub =
+ isolate()->builtins()->JSConstructStubGeneric();
__ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -3454,7 +3479,8 @@
// Slow case: Jump to runtime.
__ bind(&slow);
- __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1);
+ Counters* counters = isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
// ----------- S t a t e -------------
// -- eax : key
// -- edx : receiver
@@ -3588,10 +3614,10 @@
// processors that don't support SSE2. The code in IntegerConvert
// (code-stubs-ia32.cc) is roughly what is needed here though the
// conversion failure case does not need to be handled.
- if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) {
+ if (isolate()->cpu_features()->IsSupported(SSE2)) {
if (array_type != kExternalIntArray &&
array_type != kExternalUnsignedIntArray) {
- ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
+ ASSERT(isolate()->cpu_features()->IsSupported(SSE2));
CpuFeatures::Scope scope(SSE2);
__ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
// ecx: untagged integer value
@@ -3619,7 +3645,7 @@
break;
}
} else {
- if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) {
+ if (isolate()->cpu_features()->IsSupported(SSE3)) {
CpuFeatures::Scope scope(SSE3);
// fisttp stores values as signed integers. To represent the
// entire range of int and unsigned int arrays, store as a
@@ -3632,7 +3658,7 @@
__ pop(ecx);
__ add(Operand(esp), Immediate(kPointerSize));
} else {
- ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
+ ASSERT(isolate()->cpu_features()->IsSupported(SSE2));
CpuFeatures::Scope scope(SSE2);
// We can easily implement the correct rounding behavior for the
// range [0, 2^31-1]. For the time being, to keep this code simple,
diff --git a/src/ia32/virtual-frame-ia32.cc b/src/ia32/virtual-frame-ia32.cc
index 317028d..2613caf 100644
--- a/src/ia32/virtual-frame-ia32.cc
+++ b/src/ia32/virtual-frame-ia32.cc
@@ -1017,7 +1017,7 @@
MoveResultsToRegisters(&name, &receiver, ecx, eax);
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Builtins::kLoadIC_Initialize));
return RawCallCodeObject(ic, mode);
}
@@ -1030,7 +1030,7 @@
MoveResultsToRegisters(&key, &receiver, eax, edx);
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Builtins::kKeyedLoadIC_Initialize));
return RawCallCodeObject(ic, mode);
}
@@ -1041,8 +1041,8 @@
// Value and (if not contextual) receiver are on top of the frame.
// The IC expects name in ecx, value in eax, and receiver in edx.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ (strict_mode == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+ : Builtins::kStoreIC_Initialize));
Result value = Pop();
RelocInfo::Mode mode;
@@ -1108,8 +1108,8 @@
}
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ (strict_mode == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+ : Builtins::kKeyedStoreIC_Initialize));
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
}
@@ -1158,7 +1158,7 @@
// IC expects arg count in eax, function in edi, and the arguments
// and receiver on the stack.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Builtins::kJSConstructCall));
// Duplicate the function before preparing the frame.
PushElementAt(arg_count);
Result function = Pop();
diff --git a/src/ic.cc b/src/ic.cc
index 7e87b1b..01d4ca0 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -878,14 +878,14 @@
const int offset = String::kLengthOffset;
PatchInlinedLoad(address(), map, offset);
set_target(isolate()->builtins()->builtin(
- Builtins::LoadIC_StringLength));
+ Builtins::kLoadIC_StringLength));
} else {
set_target(isolate()->builtins()->builtin(
- Builtins::LoadIC_StringWrapperLength));
+ Builtins::kLoadIC_StringWrapperLength));
}
} else if (state == MONOMORPHIC && object->IsStringWrapper()) {
set_target(isolate()->builtins()->builtin(
- Builtins::LoadIC_StringWrapperLength));
+ Builtins::kLoadIC_StringWrapperLength));
} else {
set_target(non_monomorphic_stub);
}
@@ -908,7 +908,7 @@
const int offset = JSArray::kLengthOffset;
PatchInlinedLoad(address(), map, offset);
set_target(isolate()->builtins()->builtin(
- Builtins::LoadIC_ArrayLength));
+ Builtins::kLoadIC_ArrayLength));
} else {
set_target(non_monomorphic_stub);
}
@@ -924,7 +924,7 @@
#endif
if (state == PREMONOMORPHIC) {
set_target(isolate()->builtins()->builtin(
- Builtins::LoadIC_FunctionPrototype));
+ Builtins::kLoadIC_FunctionPrototype));
} else {
set_target(non_monomorphic_stub);
}
@@ -1451,8 +1451,8 @@
if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
#endif
Builtins::Name target = (strict_mode == kStrictMode)
- ? Builtins::StoreIC_ArrayLength_Strict
- : Builtins::StoreIC_ArrayLength;
+ ? Builtins::kStoreIC_ArrayLength_Strict
+ : Builtins::kStoreIC_ArrayLength;
set_target(isolate()->builtins()->builtin(target));
return receiver->SetProperty(*name, *value, NONE, strict_mode);
}
diff --git a/src/ic.h b/src/ic.h
index 91a626f..f226660 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -316,15 +316,15 @@
// Stub accessors.
Code* megamorphic_stub() {
return isolate()->builtins()->builtin(
- Builtins::LoadIC_Megamorphic);
+ Builtins::kLoadIC_Megamorphic);
}
static Code* initialize_stub() {
return Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_Initialize);
+ Builtins::kLoadIC_Initialize);
}
Code* pre_monomorphic_stub() {
return isolate()->builtins()->builtin(
- Builtins::LoadIC_PreMonomorphic);
+ Builtins::kLoadIC_PreMonomorphic);
}
static void Clear(Address address, Code* target);
@@ -382,28 +382,28 @@
// Stub accessors.
static Code* initialize_stub() {
return Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize);
+ Builtins::kKeyedLoadIC_Initialize);
}
Code* megamorphic_stub() {
return isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Generic);
+ Builtins::kKeyedLoadIC_Generic);
}
Code* generic_stub() {
return isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Generic);
+ Builtins::kKeyedLoadIC_Generic);
}
Code* pre_monomorphic_stub() {
return isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_PreMonomorphic);
+ Builtins::kKeyedLoadIC_PreMonomorphic);
}
Code* string_stub() {
return isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_String);
+ Builtins::kKeyedLoadIC_String);
}
Code* indexed_interceptor_stub() {
return isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_IndexedInterceptor);
+ Builtins::kKeyedLoadIC_IndexedInterceptor);
}
static void Clear(Address address, Code* target);
@@ -465,27 +465,27 @@
// Stub accessors.
Code* megamorphic_stub() {
return isolate()->builtins()->builtin(
- Builtins::StoreIC_Megamorphic);
+ Builtins::kStoreIC_Megamorphic);
}
Code* megamorphic_stub_strict() {
return isolate()->builtins()->builtin(
- Builtins::StoreIC_Megamorphic_Strict);
+ Builtins::kStoreIC_Megamorphic_Strict);
}
static Code* initialize_stub() {
return Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Initialize);
+ Builtins::kStoreIC_Initialize);
}
static Code* initialize_stub_strict() {
return Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Initialize_Strict);
+ Builtins::kStoreIC_Initialize_Strict);
}
Code* global_proxy_stub() {
return isolate()->builtins()->builtin(
- Builtins::StoreIC_GlobalProxy);
+ Builtins::kStoreIC_GlobalProxy);
}
Code* global_proxy_stub_strict() {
return isolate()->builtins()->builtin(
- Builtins::StoreIC_GlobalProxy_Strict);
+ Builtins::kStoreIC_GlobalProxy_Strict);
}
static void Clear(Address address, Code* target);
@@ -540,27 +540,27 @@
// Stub accessors.
static Code* initialize_stub() {
return Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_Initialize);
+ Builtins::kKeyedStoreIC_Initialize);
}
Code* megamorphic_stub() {
return isolate()->builtins()->builtin(
- Builtins::KeyedStoreIC_Generic);
+ Builtins::kKeyedStoreIC_Generic);
}
static Code* initialize_stub_strict() {
return Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_Initialize_Strict);
+ Builtins::kKeyedStoreIC_Initialize_Strict);
}
Code* megamorphic_stub_strict() {
return isolate()->builtins()->builtin(
- Builtins::KeyedStoreIC_Generic_Strict);
+ Builtins::kKeyedStoreIC_Generic_Strict);
}
Code* generic_stub() {
return isolate()->builtins()->builtin(
- Builtins::KeyedStoreIC_Generic);
+ Builtins::kKeyedStoreIC_Generic);
}
Code* generic_stub_strict() {
return isolate()->builtins()->builtin(
- Builtins::KeyedStoreIC_Generic_Strict);
+ Builtins::kKeyedStoreIC_Generic_Strict);
}
static void Clear(Address address, Code* target);
diff --git a/src/isolate.h b/src/isolate.h
index 13ffc13..90fce61 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -402,7 +402,8 @@
// Returns the isolate inside which the current thread is running.
INLINE(static Isolate* Current()) {
- Isolate* isolate = UncheckedCurrent();
+ Isolate* isolate = reinterpret_cast<Isolate*>(
+ Thread::GetExistingThreadLocal(isolate_key_));
ASSERT(isolate != NULL);
return isolate;
}
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 2db8ddf..d5f59ea 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -501,7 +501,8 @@
}
Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate);
- if (IrregexpInterpreter::Match(byte_codes,
+ if (IrregexpInterpreter::Match(isolate,
+ byte_codes,
subject,
register_vector,
index)) {
diff --git a/src/jump-target-heavy.cc b/src/jump-target-heavy.cc
index 28e22c0..f73e027 100644
--- a/src/jump-target-heavy.cc
+++ b/src/jump-target-heavy.cc
@@ -140,7 +140,7 @@
// the directionality of the block. Compute: an entry frame for the
// block.
- COUNTERS->compute_entry_frame()->Increment();
+ Isolate::Current()->counters()->compute_entry_frame()->Increment();
#ifdef DEBUG
if (Isolate::Current()->jump_target_compiling_deferred_code()) {
ASSERT(reaching_frames_.length() > 1);
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 555e082..dbcf5ef 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -1033,7 +1033,7 @@
shared_info->set_construct_stub(
Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructStubGeneric));
+ Builtins::kJSConstructStubGeneric));
DeoptimizeDependentFunctions(*shared_info);
Isolate::Current()->compilation_cache()->Remove(shared_info);
@@ -1404,7 +1404,7 @@
*mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL;
} else if (pre_top_frame_code ==
Isolate::Current()->builtins()->builtin(
- Builtins::FrameDropper_LiveEdit)) {
+ Builtins::kFrameDropper_LiveEdit)) {
// OK, we can drop our own code.
*mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL;
} else if (pre_top_frame_code->kind() == Code::STUB &&
@@ -1430,8 +1430,7 @@
// Make sure FixTryCatchHandler is idempotent.
ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame));
- Handle<Code> code(Isolate::Current()->builtins()->builtin(
- Builtins::FrameDropper_LiveEdit));
+ Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit();
top_frame->set_pc(code->entry());
pre_top_frame->SetCallerFp(bottom_js_frame->fp());
diff --git a/src/log.cc b/src/log.cc
index 310e197..dc7906c 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -52,24 +52,25 @@
//
class SlidingStateWindow {
public:
- SlidingStateWindow();
+ explicit SlidingStateWindow(Isolate* isolate);
~SlidingStateWindow();
void AddState(StateTag state);
private:
static const int kBufferSize = 256;
+ Counters* counters_;
int current_index_;
bool is_full_;
byte buffer_[kBufferSize];
void IncrementStateCounter(StateTag state) {
- COUNTERS->state_counters(state)->Increment();
+ counters_->state_counters(state)->Increment();
}
void DecrementStateCounter(StateTag state) {
- COUNTERS->state_counters(state)->Decrement();
+ counters_->state_counters(state)->Decrement();
}
};
@@ -238,11 +239,12 @@
//
// SlidingStateWindow implementation.
//
-SlidingStateWindow::SlidingStateWindow(): current_index_(0), is_full_(false) {
+SlidingStateWindow::SlidingStateWindow(Isolate* isolate)
+ : counters_(isolate->counters()), current_index_(0), is_full_(false) {
for (int i = 0; i < kBufferSize; i++) {
buffer_[i] = static_cast<byte>(OTHER);
}
- LOGGER->ticker_->SetWindow(this);
+ isolate->logger()->ticker_->SetWindow(this);
}
@@ -617,7 +619,7 @@
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
SmartPointer<char> property_name =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- LOGGER->ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
+ ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
#endif
}
@@ -629,7 +631,7 @@
String* class_name_obj = holder->class_name();
SmartPointer<char> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- LOGGER->ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
+ ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
#endif
}
@@ -639,7 +641,7 @@
String* class_name_obj = object->class_name();
SmartPointer<char> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- LOGGER->ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
+ ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
#endif
}
@@ -647,7 +649,7 @@
void Logger::ApiEntryCall(const char* name) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!log_->IsEnabled() || !FLAG_log_api) return;
- LOGGER->ApiEvent("api,%s\n", name);
+ ApiEvent("api,%s\n", name);
#endif
}
@@ -787,7 +789,7 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!log_->IsEnabled() || !FLAG_log_code) return;
if (code == Isolate::Current()->builtins()->builtin(
- Builtins::LazyCompile))
+ Builtins::kLazyCompile))
return;
LogMessageBuilder msg(this);
@@ -1416,7 +1418,7 @@
// GetScriptLineNumber call.
for (int i = 0; i < compiled_funcs_count; ++i) {
if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
- Builtins::LazyCompile))
+ Builtins::kLazyCompile))
continue;
Handle<SharedFunctionInfo> shared = sfis[i];
Handle<String> func_name(shared->DebugName());
@@ -1515,8 +1517,9 @@
ticker_ = new Ticker(Isolate::Current(), kSamplingIntervalMs);
+ Isolate* isolate = Isolate::Current();
if (FLAG_sliding_state_window && sliding_state_window_ == NULL) {
- sliding_state_window_ = new SlidingStateWindow();
+ sliding_state_window_ = new SlidingStateWindow(isolate);
}
bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
@@ -1528,7 +1531,7 @@
}
if (FLAG_prof) {
- profiler_ = new Profiler(Isolate::Current());
+ profiler_ = new Profiler(isolate);
if (!FLAG_prof_auto) {
profiler_->pause();
} else {
@@ -1603,7 +1606,7 @@
// Otherwise, if the sliding state window computation has not been
// started we do it now.
if (sliding_state_window_ == NULL) {
- sliding_state_window_ = new SlidingStateWindow();
+ sliding_state_window_ = new SlidingStateWindow(Isolate::Current());
}
#endif
}
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 08cf7d7..1f73388 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -247,7 +247,7 @@
private:
void ProcessJSFunctionCandidates() {
- Code* lazy_compile = isolate_->builtins()->builtin(Builtins::LazyCompile);
+ Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
JSFunction* candidate = jsfunction_candidates_head_;
JSFunction* next_candidate;
@@ -272,7 +272,7 @@
void ProcessSharedFunctionInfoCandidates() {
- Code* lazy_compile = isolate_->builtins()->builtin(Builtins::LazyCompile);
+ Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
SharedFunctionInfo* next_candidate;
@@ -570,12 +570,12 @@
inline static bool IsCompiled(JSFunction* function) {
return function->unchecked_code() !=
- Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
+ Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
}
inline static bool IsCompiled(SharedFunctionInfo* function) {
return function->unchecked_code() !=
- Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
+ Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
}
inline static bool IsFlushable(JSFunction* function) {
@@ -1101,11 +1101,11 @@
ASSERT(contents->IsFixedArray());
ASSERT(contents->length() >= 2);
SetMark(contents);
- // Contents contains (value, details) pairs. If the details say that
- // the type of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION, or
- // NULL_DESCRIPTOR, we don't mark the value as live. Only for
- // MAP_TRANSITION and CONSTANT_TRANSITION is the value an Object* (a
- // Map*).
+ // Contents contains (value, details) pairs. If the details say that the type
+ // of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION,
+ // EXTERNAL_ARRAY_TRANSITION or NULL_DESCRIPTOR, we don't mark the value as
+ // live. Only for MAP_TRANSITION, EXTERNAL_ARRAY_TRANSITION and
+ // CONSTANT_TRANSITION is the value an Object* (a Map*).
for (int i = 0; i < contents->length(); i += 2) {
// If the pair (value, details) at index i, i+1 is not
// a transition or null descriptor, mark the value.
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 416f887..99e9819 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -170,14 +170,15 @@
// A copy of the PropertyType enum from global.h
PropertyType = {};
-PropertyType.Normal = 0;
-PropertyType.Field = 1;
-PropertyType.ConstantFunction = 2;
-PropertyType.Callbacks = 3;
-PropertyType.Interceptor = 4;
-PropertyType.MapTransition = 5;
-PropertyType.ConstantTransition = 6;
-PropertyType.NullDescriptor = 7;
+PropertyType.Normal = 0;
+PropertyType.Field = 1;
+PropertyType.ConstantFunction = 2;
+PropertyType.Callbacks = 3;
+PropertyType.Interceptor = 4;
+PropertyType.MapTransition = 5;
+PropertyType.ExternalArrayTransition = 6;
+PropertyType.ConstantTransition = 7;
+PropertyType.NullDescriptor = 8;
// Different attributes for a property.
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 922c054..36e5c6f 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1722,7 +1722,8 @@
bool DescriptorArray::IsTransition(int descriptor_number) {
PropertyType t = GetType(descriptor_number);
- return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
+ return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
+ t == EXTERNAL_ARRAY_TRANSITION;
}
@@ -2871,21 +2872,6 @@
}
-MaybeObject* Map::NewExternalArrayElementsMap() {
- // TODO(danno): Special case empty object map (or most common case)
- // to return a pre-canned pixel array map.
- Object* obj;
- { MaybeObject* maybe_obj = CopyDropTransitions();
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- Map* new_map = Map::cast(obj);
- new_map->set_has_fast_elements(false);
- new_map->set_has_external_array_elements(true);
- isolate()->counters()->map_to_external_array_elements()->Increment();
- return new_map;
-}
-
-
ACCESSORS(Map, instance_descriptors, DescriptorArray,
kInstanceDescriptorsOffset)
ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
@@ -3220,7 +3206,7 @@
bool SharedFunctionInfo::is_compiled() {
return code() !=
- Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
+ Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
}
@@ -3280,7 +3266,7 @@
bool JSFunction::IsMarkedForLazyRecompilation() {
- return code() == GetIsolate()->builtins()->builtin(Builtins::LazyRecompile);
+ return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
}
@@ -3394,7 +3380,7 @@
bool JSFunction::is_compiled() {
- return code() != GetIsolate()->builtins()->builtin(Builtins::LazyCompile);
+ return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
}
diff --git a/src/objects.cc b/src/objects.cc
index a2b35ef..a0d1536 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1282,12 +1282,21 @@
}
}
- // Only allow map transition if the object's map is NOT equal to the
- // global object_function's map and there is not a transition for name.
+ // Only allow map transition if the object isn't the global object and there
+ // is not a transition for the name, or there's a transition for the name but
+ // it's unrelated to properties.
+ int descriptor_index = old_descriptors->Search(name);
+
+ // External array transitions are stored in the descriptor for property "",
+ // which is not a identifier and should have forced a switch to slow
+ // properties above.
+ ASSERT(descriptor_index == DescriptorArray::kNotFound ||
+ old_descriptors->GetType(descriptor_index) != EXTERNAL_ARRAY_TRANSITION);
+ bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound ||
+ old_descriptors->GetType(descriptor_index) == EXTERNAL_ARRAY_TRANSITION;
bool allow_map_transition =
- !old_descriptors->Contains(name) &&
- (isolate->context()->global_context()->object_function()->
- map() != map());
+ can_insert_transition &&
+ (isolate->context()->global_context()->object_function()->map() != map());
ASSERT(index < map()->inobject_properties() ||
(index - map()->inobject_properties()) < properties()->length() ||
@@ -1438,13 +1447,19 @@
MaybeObject* JSObject::AddProperty(String* name,
Object* value,
- PropertyAttributes attributes) {
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
ASSERT(!IsJSGlobalProxy());
Heap* heap = GetHeap();
if (!map()->is_extensible()) {
- Handle<Object> args[1] = {Handle<String>(name)};
- return heap->isolate()->Throw(
- *FACTORY->NewTypeError("object_not_extensible", HandleVector(args, 1)));
+ if (strict_mode == kNonStrictMode) {
+ return heap->undefined_value();
+ } else {
+ Handle<Object> args[1] = {Handle<String>(name)};
+ return heap->isolate()->Throw(
+ *FACTORY->NewTypeError("object_not_extensible",
+ HandleVector(args, 1)));
+ }
}
if (HasFastProperties()) {
// Ensure the descriptor array does not get too big.
@@ -1485,7 +1500,7 @@
return SetProperty(&result, name, value, attributes, strict_mode);
}
// Add a new real property.
- return AddProperty(name, value, attributes);
+ return AddProperty(name, value, attributes, strict_mode);
}
@@ -1819,6 +1834,77 @@
}
+MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type,
+ bool safe_to_add_transition) {
+ DescriptorArray* descriptors = instance_descriptors();
+ String* external_array_sentinel_name = GetIsolate()->heap()->empty_symbol();
+
+ if (safe_to_add_transition) {
+ // It's only safe to manipulate the descriptor array if it would be
+ // safe to add a transition.
+
+ ASSERT(!is_shared()); // no transitions can be added to shared maps.
+ // Check if the external array transition already exists.
+ DescriptorLookupCache* cache = heap()->isolate()->descriptor_lookup_cache();
+ int index = cache->Lookup(descriptors, external_array_sentinel_name);
+ if (index == DescriptorLookupCache::kAbsent) {
+ index = descriptors->Search(external_array_sentinel_name);
+ cache->Update(descriptors,
+ external_array_sentinel_name,
+ index);
+ }
+
+ // If the transition already exists, check the type. If there is a match,
+ // return it.
+ if (index != DescriptorArray::kNotFound) {
+ PropertyDetails details(PropertyDetails(descriptors->GetDetails(index)));
+ if (details.type() == EXTERNAL_ARRAY_TRANSITION &&
+ details.array_type() == array_type) {
+ return descriptors->GetValue(index);
+ } else {
+ safe_to_add_transition = false;
+ }
+ }
+ }
+
+ // No transition to an existing external array map. Make a new one.
+ Object* obj;
+ { MaybeObject* maybe_map = CopyDropTransitions();
+ if (!maybe_map->ToObject(&obj)) return maybe_map;
+ }
+ Map* new_map = Map::cast(obj);
+
+ new_map->set_has_fast_elements(false);
+ new_map->set_has_external_array_elements(true);
+ GetIsolate()->counters()->map_to_external_array_elements()->Increment();
+
+ // Only remember the map transition if the object's map is NOT equal to the
+ // global object_function's map and there is not an already existing
+ // non-matching external array transition.
+ bool allow_map_transition =
+ safe_to_add_transition &&
+ (GetIsolate()->context()->global_context()->object_function()->map() !=
+ map());
+ if (allow_map_transition) {
+ // Allocate new instance descriptors for the old map with map transition.
+ ExternalArrayTransitionDescriptor desc(external_array_sentinel_name,
+ Map::cast(new_map),
+ array_type);
+ Object* new_descriptors;
+ MaybeObject* maybe_new_descriptors = descriptors->CopyInsert(
+ &desc,
+ KEEP_TRANSITIONS);
+ if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
+ return maybe_new_descriptors;
+ }
+ descriptors = DescriptorArray::cast(new_descriptors);
+ set_instance_descriptors(descriptors);
+ }
+
+ return new_map;
+}
+
+
void JSObject::LocalLookupRealNamedProperty(String* name,
LookupResult* result) {
if (IsJSGlobalProxy()) {
@@ -1989,7 +2075,7 @@
}
if (!result->IsFound()) {
// Neither properties nor transitions found.
- return AddProperty(name, value, attributes);
+ return AddProperty(name, value, attributes, strict_mode);
}
if (result->IsReadOnly() && result->IsProperty()) {
if (strict_mode == kStrictMode) {
@@ -2051,6 +2137,7 @@
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
}
case NULL_DESCRIPTOR:
+ case EXTERNAL_ARRAY_TRANSITION:
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
default:
UNREACHABLE();
@@ -2096,7 +2183,7 @@
// Check for accessor in prototype chain removed here in clone.
if (!result.IsFound()) {
// Neither properties nor transitions found.
- return AddProperty(name, value, attributes);
+ return AddProperty(name, value, attributes, kNonStrictMode);
}
PropertyDetails details = PropertyDetails(attributes, NORMAL);
@@ -2130,6 +2217,7 @@
// if the value is a function.
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
case NULL_DESCRIPTOR:
+ case EXTERNAL_ARRAY_TRANSITION:
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
default:
UNREACHABLE();
@@ -2273,6 +2361,7 @@
MaybeObject* NormalizedMapCache::Get(JSObject* obj,
PropertyNormalizationMode mode) {
+ Isolate* isolate = obj->GetIsolate();
Map* fast = obj->map();
int index = Hash(fast) % kEntries;
Object* result = get(index);
@@ -2299,7 +2388,7 @@
if (!maybe_result->ToObject(&result)) return maybe_result;
}
set(index, result);
- COUNTERS->normalized_maps()->Increment();
+ isolate->counters()->normalized_maps()->Increment();
return result;
}
@@ -2359,7 +2448,7 @@
UNIQUE_NORMALIZED_MAP);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
- COUNTERS->normalized_maps()->Increment();
+ GetIsolate()->counters()->normalized_maps()->Increment();
set_map(Map::cast(obj));
}
@@ -5484,6 +5573,7 @@
DescriptorArray* descriptors = instance_descriptors();
for (int i = 0; i < descriptors->number_of_descriptors(); i++) {
if (descriptors->GetType(i) == MAP_TRANSITION ||
+ descriptors->GetType(i) == EXTERNAL_ARRAY_TRANSITION ||
descriptors->GetType(i) == CONSTANT_TRANSITION) {
// Get target.
Map* target = Map::cast(descriptors->GetValue(i));
@@ -5526,6 +5616,7 @@
// non-live object.
PropertyDetails details(Smi::cast(contents->get(i + 1)));
if (details.type() == MAP_TRANSITION ||
+ details.type() == EXTERNAL_ARRAY_TRANSITION ||
details.type() == CONSTANT_TRANSITION) {
Map* target = reinterpret_cast<Map*>(contents->get(i));
ASSERT(target->IsHeapObject());
@@ -5557,7 +5648,7 @@
ASSERT(shared()->allows_lazy_compilation() ||
code()->optimizable());
Builtins* builtins = GetIsolate()->builtins();
- ReplaceCode(builtins->builtin(Builtins::LazyRecompile));
+ ReplaceCode(builtins->builtin(Builtins::kLazyRecompile));
}
@@ -5937,9 +6028,9 @@
}
set_initial_map(map);
Builtins* builtins = map->heap()->isolate()->builtins();
- ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric),
+ ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric),
construct_stub());
- set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown));
+ set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown));
}
@@ -5958,9 +6049,9 @@
// several more GCs) CompleteInobjectSlackTracking will eventually be called.
set_initial_map(map->heap()->raw_unchecked_undefined_value());
Builtins* builtins = map->heap()->isolate()->builtins();
- ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown),
+ ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown),
*RawField(this, kConstructStubOffset));
- set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric));
+ set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric));
// It is safe to clear the flag: it will be set again if the map is live.
set_live_objects_may_exist(false);
}
@@ -5974,9 +6065,9 @@
// Resume inobject slack tracking.
set_initial_map(map);
Builtins* builtins = map->heap()->isolate()->builtins();
- ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric),
+ ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric),
*RawField(this, kConstructStubOffset));
- set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown));
+ set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown));
// The map survived the gc, so there may be objects referencing it.
set_live_objects_may_exist(true);
}
@@ -6008,9 +6099,9 @@
Heap* heap = map->heap();
set_initial_map(heap->undefined_value());
Builtins* builtins = heap->isolate()->builtins();
- ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown),
+ ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown),
construct_stub());
- set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric));
+ set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric));
int slack = map->unused_property_fields();
map->TraverseTransitionTree(&GetMinInobjectSlack, &slack);
@@ -6399,6 +6490,7 @@
case CALLBACKS: return "CALLBACKS";
case INTERCEPTOR: return "INTERCEPTOR";
case MAP_TRANSITION: return "MAP_TRANSITION";
+ case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION";
case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
}
@@ -7345,13 +7437,17 @@
// When we set the is_extensible flag to false we always force
// the element into dictionary mode (and force them to stay there).
if (!map()->is_extensible()) {
- Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
- Handle<String> index_string(
- isolate->factory()->NumberToString(number));
- Handle<Object> args[1] = { index_string };
- return isolate->Throw(
- *isolate->factory()->NewTypeError("object_not_extensible",
- HandleVector(args, 1)));
+ if (strict_mode == kNonStrictMode) {
+ return isolate->heap()->undefined_value();
+ } else {
+ Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
+ Handle<String> index_string(
+ isolate->factory()->NumberToString(number));
+ Handle<Object> args[1] = { index_string };
+ return isolate->Throw(
+ *isolate->factory()->NewTypeError("object_not_extensible",
+ HandleVector(args, 1)));
+ }
}
Object* result;
{ MaybeObject* maybe_result = dictionary->AtNumberPut(index, value);
@@ -7489,9 +7585,9 @@
// callbacks or interceptor calls.
AssertNoContextChange ncc;
HandleScope scope(isolate);
- Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
- Handle<Object> this_handle(receiver);
- Handle<JSObject> holder_handle(this);
+ Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate);
+ Handle<Object> this_handle(receiver, isolate);
+ Handle<JSObject> holder_handle(this, isolate);
if (!interceptor->getter()->IsUndefined()) {
v8::IndexedPropertyGetter getter =
diff --git a/src/objects.h b/src/objects.h
index e0ea064..96e5cb6 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -135,19 +135,37 @@
PropertyDetails(PropertyAttributes attributes,
PropertyType type,
int index = 0) {
+ ASSERT(type != EXTERNAL_ARRAY_TRANSITION);
ASSERT(TypeField::is_valid(type));
ASSERT(AttributesField::is_valid(attributes));
- ASSERT(IndexField::is_valid(index));
+ ASSERT(StorageField::is_valid(index));
value_ = TypeField::encode(type)
| AttributesField::encode(attributes)
- | IndexField::encode(index);
+ | StorageField::encode(index);
ASSERT(type == this->type());
ASSERT(attributes == this->attributes());
ASSERT(index == this->index());
}
+ PropertyDetails(PropertyAttributes attributes,
+ PropertyType type,
+ ExternalArrayType array_type) {
+ ASSERT(type == EXTERNAL_ARRAY_TRANSITION);
+ ASSERT(TypeField::is_valid(type));
+ ASSERT(AttributesField::is_valid(attributes));
+ ASSERT(StorageField::is_valid(static_cast<int>(array_type)));
+
+ value_ = TypeField::encode(type)
+ | AttributesField::encode(attributes)
+ | StorageField::encode(static_cast<int>(array_type));
+
+ ASSERT(type == this->type());
+ ASSERT(attributes == this->attributes());
+ ASSERT(array_type == this->array_type());
+ }
+
// Conversion for storing details as Object*.
inline PropertyDetails(Smi* smi);
inline Smi* AsSmi();
@@ -157,7 +175,8 @@
bool IsTransition() {
PropertyType t = type();
ASSERT(t != INTERCEPTOR);
- return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
+ return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
+ t == EXTERNAL_ARRAY_TRANSITION;
}
bool IsProperty() {
@@ -166,11 +185,18 @@
PropertyAttributes attributes() { return AttributesField::decode(value_); }
- int index() { return IndexField::decode(value_); }
+ int index() { return StorageField::decode(value_); }
+
+ ExternalArrayType array_type() {
+ ASSERT(type() == EXTERNAL_ARRAY_TRANSITION);
+ return static_cast<ExternalArrayType>(StorageField::decode(value_));
+ }
inline PropertyDetails AsDeleted();
- static bool IsValidIndex(int index) { return IndexField::is_valid(index); }
+ static bool IsValidIndex(int index) {
+ return StorageField::is_valid(index);
+ }
bool IsReadOnly() { return (attributes() & READ_ONLY) != 0; }
bool IsDontDelete() { return (attributes() & DONT_DELETE) != 0; }
@@ -179,10 +205,10 @@
// Bit fields in value_ (type, shift, size). Must be public so the
// constants can be embedded in generated code.
- class TypeField: public BitField<PropertyType, 0, 3> {};
- class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
- class DeletedField: public BitField<uint32_t, 6, 1> {};
- class IndexField: public BitField<uint32_t, 7, 32-7> {};
+ class TypeField: public BitField<PropertyType, 0, 4> {};
+ class AttributesField: public BitField<PropertyAttributes, 4, 3> {};
+ class DeletedField: public BitField<uint32_t, 7, 1> {};
+ class StorageField: public BitField<uint32_t, 8, 32-8> {};
static const int kInitialIndex = 1;
private:
@@ -557,6 +583,8 @@
FIRST_FUNCTION_CLASS_TYPE = JS_REGEXP_TYPE
};
+static const int kExternalArrayTypeCount = LAST_EXTERNAL_ARRAY_TYPE -
+ FIRST_EXTERNAL_ARRAY_TYPE + 1;
STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType);
STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
@@ -1691,7 +1719,8 @@
// Add a property to an object.
MUST_USE_RESULT MaybeObject* AddProperty(String* name,
Object* value,
- PropertyAttributes attributes);
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode);
// Convert the object to use the canonical dictionary
// representation. If the object is expected to have additional properties
@@ -3502,18 +3531,18 @@
static const int kFlagsICStateShift = 0;
static const int kFlagsICInLoopShift = 3;
static const int kFlagsTypeShift = 4;
- static const int kFlagsKindShift = 7;
- static const int kFlagsICHolderShift = 11;
- static const int kFlagsExtraICStateShift = 12;
- static const int kFlagsArgumentsCountShift = 14;
+ static const int kFlagsKindShift = 8;
+ static const int kFlagsICHolderShift = 12;
+ static const int kFlagsExtraICStateShift = 13;
+ static const int kFlagsArgumentsCountShift = 15;
static const int kFlagsICStateMask = 0x00000007; // 00000000111
static const int kFlagsICInLoopMask = 0x00000008; // 00000001000
- static const int kFlagsTypeMask = 0x00000070; // 00001110000
- static const int kFlagsKindMask = 0x00000780; // 11110000000
- static const int kFlagsCacheInPrototypeMapMask = 0x00000800;
- static const int kFlagsExtraICStateMask = 0x00003000;
- static const int kFlagsArgumentsCountMask = 0xFFFFC000;
+ static const int kFlagsTypeMask = 0x000000F0; // 00001110000
+ static const int kFlagsKindMask = 0x00000F00; // 11110000000
+ static const int kFlagsCacheInPrototypeMapMask = 0x00001000;
+ static const int kFlagsExtraICStateMask = 0x00006000;
+ static const int kFlagsArgumentsCountMask = 0xFFFF8000;
static const int kFlagsNotUsedInLookup =
(kFlagsICInLoopMask | kFlagsTypeMask | kFlagsCacheInPrototypeMapMask);
@@ -3715,7 +3744,9 @@
// Returns a new map with all transitions dropped from the descriptors and the
// external array elements bit set.
- MUST_USE_RESULT inline MaybeObject* NewExternalArrayElementsMap();
+ MUST_USE_RESULT MaybeObject* GetExternalArrayElementsMap(
+ ExternalArrayType array_type,
+ bool safe_to_add_transition);
// Returns the property index for name (only valid for FAST MODE).
int PropertyIndexFor(String* name);
diff --git a/src/parser.cc b/src/parser.cc
index 7dbb09d..eefe7cf 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -284,7 +284,7 @@
symbol_cache_.at(symbol_id) = result;
return result;
}
- COUNTERS->total_preparse_symbols_skipped()->Increment();
+ isolate()->counters()->total_preparse_symbols_skipped()->Increment();
return result;
}
@@ -599,8 +599,8 @@
StrictModeFlag strict_mode) {
CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
- HistogramTimerScope timer(COUNTERS->parse());
- COUNTERS->total_parse_size()->Increment(source->length());
+ HistogramTimerScope timer(isolate()->counters()->parse());
+ isolate()->counters()->total_parse_size()->Increment(source->length());
fni_ = new FuncNameInferrer();
// Initialize parser state.
@@ -681,9 +681,9 @@
FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
- HistogramTimerScope timer(COUNTERS->parse_lazy());
+ HistogramTimerScope timer(isolate()->counters()->parse_lazy());
Handle<String> source(String::cast(script_->source()));
- COUNTERS->total_parse_size()->Increment(source->length());
+ isolate()->counters()->total_parse_size()->Increment(source->length());
Handle<SharedFunctionInfo> shared_info = info->shared_info();
// Initialize parser state.
@@ -3608,7 +3608,7 @@
// End position greater than end of stream is safe, and hard to check.
ReportInvalidPreparseData(name, CHECK_OK);
}
- COUNTERS->total_preparse_skipped()->Increment(
+ isolate()->counters()->total_preparse_skipped()->Increment(
end_pos - function_block_pos);
// Seek to position just before terminal '}'.
scanner().SeekForward(end_pos - 1);
diff --git a/src/platform-tls-mac.h b/src/platform-tls-mac.h
new file mode 100644
index 0000000..86a3347
--- /dev/null
+++ b/src/platform-tls-mac.h
@@ -0,0 +1,62 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PLATFORM_TLS_MAC_H_
+#define V8_PLATFORM_TLS_MAC_H_
+
+#include "globals.h"
+
+namespace v8 {
+namespace internal {
+
+#if defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64)
+
+#define V8_FAST_TLS_SUPPORTED 1
+
+INLINE(intptr_t InternalGetExistingThreadLocal(intptr_t index));
+
+inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
+ // The constants below are taken from pthreads.s from the XNU kernel
+ // sources archive at www.opensource.apple.com.
+ intptr_t result;
+#if defined(V8_HOST_ARCH_IA32)
+ asm("movl %%gs:0x48(,%1,4), %0;"
+ :"=r"(result) // Output must be a writable register.
+ :"0"(index)); // Input is the same as output.
+#else
+ asm("movq %%gs:0x60(,%1,8), %0;"
+ :"=r"(result)
+ :"0"(index));
+#endif
+ return result;
+}
+
+#endif
+
+} } // namespace v8::internal
+
+#endif // V8_PLATFORM_TLS_MAC_H_
diff --git a/src/platform-tls-win32.h b/src/platform-tls-win32.h
new file mode 100644
index 0000000..4056e8c
--- /dev/null
+++ b/src/platform-tls-win32.h
@@ -0,0 +1,62 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PLATFORM_TLS_WIN32_H_
+#define V8_PLATFORM_TLS_WIN32_H_
+
+#include "checks.h"
+#include "globals.h"
+#include "win32-headers.h"
+
+namespace v8 {
+namespace internal {
+
+#if defined(_WIN32) && !defined(_WIN64)
+
+#define V8_FAST_TLS_SUPPORTED 1
+
+inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
+ const intptr_t kTibInlineTlsOffset = 0xE10;
+ const intptr_t kTibExtraTlsOffset = 0xF94;
+ const intptr_t kMaxInlineSlots = 64;
+ const intptr_t kMaxSlots = kMaxInlineSlots + 1024;
+ ASSERT(0 <= index && index < kMaxSlots);
+ if (index < kMaxInlineSlots) {
+ return static_cast<intptr_t>(__readfsdword(kTibInlineTlsOffset +
+ kPointerSize * index));
+ }
+ intptr_t extra = static_cast<intptr_t>(__readfsdword(kTibExtraTlsOffset));
+ ASSERT(extra != 0);
+ return *reinterpret_cast<intptr_t*>(extra +
+ kPointerSize * (index - kMaxInlineSlots));
+}
+
+#endif
+
+} } // namespace v8::internal
+
+#endif // V8_PLATFORM_TLS_WIN32_H_
diff --git a/src/platform-tls.h b/src/platform-tls.h
new file mode 100644
index 0000000..5649175
--- /dev/null
+++ b/src/platform-tls.h
@@ -0,0 +1,50 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Platform and architecture specific thread local store functions.
+
+#ifndef V8_PLATFORM_TLS_H_
+#define V8_PLATFORM_TLS_H_
+
+#ifdef V8_FAST_TLS
+
+// When fast TLS is requested we include the appropriate
+// implementation header.
+//
+// The implementation header defines V8_FAST_TLS_SUPPORTED if it
+// provides fast TLS support for the current platform and architecture
+// combination.
+
+#if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
+#include "platform-tls-win32.h"
+#elif defined(__APPLE__)
+#include "platform-tls-mac.h"
+#endif
+
+#endif
+
+#endif // V8_PLATFORM_TLS_H_
diff --git a/src/platform.h b/src/platform.h
index 43291cf..4f34abe 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -114,6 +114,7 @@
#endif // __GNUC__
#include "atomicops.h"
+#include "platform-tls.h"
#include "utils.h"
#include "v8globals.h"
@@ -428,6 +429,19 @@
return GetThreadLocal(key) != NULL;
}
+#ifdef V8_FAST_TLS_SUPPORTED
+ static inline void* GetExistingThreadLocal(LocalStorageKey key) {
+ void* result = reinterpret_cast<void*>(
+ InternalGetExistingThreadLocal(static_cast<intptr_t>(key)));
+ ASSERT(result == GetThreadLocal(key));
+ return result;
+ }
+#else
+ static inline void* GetExistingThreadLocal(LocalStorageKey key) {
+ return GetThreadLocal(key);
+ }
+#endif
+
// A hint to the scheduler to let another thread run.
static void YieldCPU();
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index 42467c3..043ad1c 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -606,7 +606,8 @@
ast_printer_->inc_indent();
}
- explicit IndentedScope(const char* txt, AstNode* node = NULL) {
+ IndentedScope(AstPrinter* printer, const char* txt, AstNode* node = NULL)
+ : ast_printer_(printer) {
ast_printer_->PrintIndented(txt);
if (node != NULL && node->AsExpression() != NULL) {
Expression* expr = node->AsExpression();
@@ -698,14 +699,14 @@
void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
- IndentedScope indent(s, node);
+ IndentedScope indent(this, s, node);
Visit(node);
}
const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
Init();
- { IndentedScope indent("FUNC");
+ { IndentedScope indent(this, "FUNC");
PrintLiteralIndented("NAME", program->name(), true);
PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
PrintParameters(program->scope());
@@ -718,7 +719,7 @@
void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
if (declarations->length() > 0) {
- IndentedScope indent("DECLS");
+ IndentedScope indent(this, "DECLS");
for (int i = 0; i < declarations->length(); i++) {
Visit(declarations->at(i));
}
@@ -728,7 +729,7 @@
void AstPrinter::PrintParameters(Scope* scope) {
if (scope->num_parameters() > 0) {
- IndentedScope indent("PARAMS");
+ IndentedScope indent(this, "PARAMS");
for (int i = 0; i < scope->num_parameters(); i++) {
PrintLiteralWithModeIndented("VAR", scope->parameter(i),
scope->parameter(i)->name(),
@@ -754,10 +755,10 @@
void AstPrinter::PrintCaseClause(CaseClause* clause) {
if (clause->is_default()) {
- IndentedScope indent("DEFAULT");
+ IndentedScope indent(this, "DEFAULT");
PrintStatements(clause->statements());
} else {
- IndentedScope indent("CASE");
+ IndentedScope indent(this, "CASE");
Visit(clause->label());
PrintStatements(clause->statements());
}
@@ -766,7 +767,7 @@
void AstPrinter::VisitBlock(Block* node) {
const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
- IndentedScope indent(block_txt);
+ IndentedScope indent(this, block_txt);
PrintStatements(node->statements());
}
@@ -834,7 +835,7 @@
void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
- IndentedScope indent("SWITCH");
+ IndentedScope indent(this, "SWITCH");
PrintLabelsIndented(NULL, node->labels());
PrintIndentedVisit("TAG", node->tag());
for (int i = 0; i < node->cases()->length(); i++) {
@@ -844,7 +845,7 @@
void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
- IndentedScope indent("DO");
+ IndentedScope indent(this, "DO");
PrintLabelsIndented(NULL, node->labels());
PrintIndentedVisit("BODY", node->body());
PrintIndentedVisit("COND", node->cond());
@@ -852,7 +853,7 @@
void AstPrinter::VisitWhileStatement(WhileStatement* node) {
- IndentedScope indent("WHILE");
+ IndentedScope indent(this, "WHILE");
PrintLabelsIndented(NULL, node->labels());
PrintIndentedVisit("COND", node->cond());
PrintIndentedVisit("BODY", node->body());
@@ -860,7 +861,7 @@
void AstPrinter::VisitForStatement(ForStatement* node) {
- IndentedScope indent("FOR");
+ IndentedScope indent(this, "FOR");
PrintLabelsIndented(NULL, node->labels());
if (node->init()) PrintIndentedVisit("INIT", node->init());
if (node->cond()) PrintIndentedVisit("COND", node->cond());
@@ -870,7 +871,7 @@
void AstPrinter::VisitForInStatement(ForInStatement* node) {
- IndentedScope indent("FOR IN");
+ IndentedScope indent(this, "FOR IN");
PrintIndentedVisit("FOR", node->each());
PrintIndentedVisit("IN", node->enumerable());
PrintIndentedVisit("BODY", node->body());
@@ -878,7 +879,7 @@
void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
- IndentedScope indent("TRY CATCH");
+ IndentedScope indent(this, "TRY CATCH");
PrintIndentedVisit("TRY", node->try_block());
PrintIndentedVisit("CATCHVAR", node->catch_var());
PrintIndentedVisit("CATCH", node->catch_block());
@@ -886,19 +887,19 @@
void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
- IndentedScope indent("TRY FINALLY");
+ IndentedScope indent(this, "TRY FINALLY");
PrintIndentedVisit("TRY", node->try_block());
PrintIndentedVisit("FINALLY", node->finally_block());
}
void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
- IndentedScope indent("DEBUGGER");
+ IndentedScope indent(this, "DEBUGGER");
}
void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
- IndentedScope indent("FUNC LITERAL");
+ IndentedScope indent(this, "FUNC LITERAL");
PrintLiteralIndented("NAME", node->name(), false);
PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
PrintParameters(node->scope());
@@ -911,13 +912,13 @@
void AstPrinter::VisitSharedFunctionInfoLiteral(
SharedFunctionInfoLiteral* node) {
- IndentedScope indent("FUNC LITERAL");
+ IndentedScope indent(this, "FUNC LITERAL");
PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true);
}
void AstPrinter::VisitConditional(Conditional* node) {
- IndentedScope indent("CONDITIONAL");
+ IndentedScope indent(this, "CONDITIONAL");
PrintIndentedVisit("?", node->condition());
PrintIndentedVisit("THEN", node->then_expression());
PrintIndentedVisit("ELSE", node->else_expression());
@@ -930,14 +931,14 @@
void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
- IndentedScope indent("REGEXP LITERAL");
+ IndentedScope indent(this, "REGEXP LITERAL");
PrintLiteralIndented("PATTERN", node->pattern(), false);
PrintLiteralIndented("FLAGS", node->flags(), false);
}
void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
- IndentedScope indent("OBJ LITERAL");
+ IndentedScope indent(this, "OBJ LITERAL");
for (int i = 0; i < node->properties()->length(); i++) {
const char* prop_kind = NULL;
switch (node->properties()->at(i)->kind()) {
@@ -962,7 +963,7 @@
default:
UNREACHABLE();
}
- IndentedScope prop(prop_kind);
+ IndentedScope prop(this, prop_kind);
PrintIndentedVisit("KEY", node->properties()->at(i)->key());
PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
}
@@ -970,9 +971,9 @@
void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
- IndentedScope indent("ARRAY LITERAL");
+ IndentedScope indent(this, "ARRAY LITERAL");
if (node->values()->length() > 0) {
- IndentedScope indent("VALUES");
+ IndentedScope indent(this, "VALUES");
for (int i = 0; i < node->values()->length(); i++) {
Visit(node->values()->at(i));
}
@@ -981,7 +982,7 @@
void AstPrinter::VisitCatchExtensionObject(CatchExtensionObject* node) {
- IndentedScope indent("CatchExtensionObject");
+ IndentedScope indent(this, "CatchExtensionObject");
PrintIndentedVisit("KEY", node->key());
PrintIndentedVisit("VALUE", node->value());
}
@@ -1006,7 +1007,7 @@
void AstPrinter::VisitAssignment(Assignment* node) {
- IndentedScope indent(Token::Name(node->op()), node);
+ IndentedScope indent(this, Token::Name(node->op()), node);
Visit(node->target());
Visit(node->value());
}
@@ -1018,7 +1019,7 @@
void AstPrinter::VisitProperty(Property* node) {
- IndentedScope indent("PROPERTY", node);
+ IndentedScope indent(this, "PROPERTY", node);
Visit(node->obj());
Literal* literal = node->key()->AsLiteral();
if (literal != NULL && literal->handle()->IsSymbol()) {
@@ -1030,14 +1031,14 @@
void AstPrinter::VisitCall(Call* node) {
- IndentedScope indent("CALL");
+ IndentedScope indent(this, "CALL");
Visit(node->expression());
PrintArguments(node->arguments());
}
void AstPrinter::VisitCallNew(CallNew* node) {
- IndentedScope indent("CALL NEW");
+ IndentedScope indent(this, "CALL NEW");
Visit(node->expression());
PrintArguments(node->arguments());
}
@@ -1076,14 +1077,14 @@
void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
- IndentedScope indent(Token::Name(node->op()), node);
+ IndentedScope indent(this, Token::Name(node->op()), node);
Visit(node->left());
Visit(node->right());
}
void AstPrinter::VisitCompareOperation(CompareOperation* node) {
- IndentedScope indent(Token::Name(node->op()), node);
+ IndentedScope indent(this, Token::Name(node->op()), node);
Visit(node->left());
Visit(node->right());
}
@@ -1093,13 +1094,13 @@
const char* name = node->is_strict()
? "COMPARE-TO-NULL-STRICT"
: "COMPARE-TO-NULL";
- IndentedScope indent(name, node);
+ IndentedScope indent(this, name, node);
Visit(node->expression());
}
void AstPrinter::VisitThisFunction(ThisFunction* node) {
- IndentedScope indent("THIS-FUNCTION");
+ IndentedScope indent(this, "THIS-FUNCTION");
}
diff --git a/src/property.cc b/src/property.cc
index 9677433..c35fb83 100644
--- a/src/property.cc
+++ b/src/property.cc
@@ -52,6 +52,12 @@
GetTransitionMap()->Print(out);
PrintF(out, "\n");
break;
+ case EXTERNAL_ARRAY_TRANSITION:
+ PrintF(out, " -type = external array transition\n");
+ PrintF(out, " -map:\n");
+ GetTransitionMap()->Print(out);
+ PrintF(out, "\n");
+ break;
case CONSTANT_FUNCTION:
PrintF(out, " -type = constant function\n");
PrintF(out, " -function:\n");
diff --git a/src/property.h b/src/property.h
index 98d1c89..fa3916e 100644
--- a/src/property.h
+++ b/src/property.h
@@ -110,6 +110,16 @@
: Descriptor(key, map, attributes, MAP_TRANSITION) { }
};
+class ExternalArrayTransitionDescriptor: public Descriptor {
+ public:
+ ExternalArrayTransitionDescriptor(String* key,
+ Map* map,
+ ExternalArrayType array_type)
+ : Descriptor(key, map, PropertyDetails(NONE,
+ EXTERNAL_ARRAY_TRANSITION,
+ array_type)) { }
+};
+
// Marks a field name in a map so that adding the field is guaranteed
// to create a FIELD descriptor in the new map. Used after adding
// a constant function the first time, creating a CONSTANT_FUNCTION
@@ -262,7 +272,8 @@
Map* GetTransitionMap() {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == MAP_TRANSITION || type() == CONSTANT_TRANSITION);
+ ASSERT(type() == MAP_TRANSITION || type() == CONSTANT_TRANSITION ||
+ type() == EXTERNAL_ARRAY_TRANSITION);
return Map::cast(GetValue());
}
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 98dc00b..c6e2b46 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -197,7 +197,7 @@
MaybeObject* maybe_check_code = check_stub.TryGetCode();
if (maybe_check_code->ToObject(&check_code)) {
Code* replacement_code =
- isolate_->builtins()->builtin(Builtins::OnStackReplacement);
+ isolate_->builtins()->builtin(Builtins::kOnStackReplacement);
Code* unoptimized_code = shared->code();
Deoptimizer::PatchStackCheckCode(unoptimized_code,
Code::cast(check_code),
diff --git a/src/runtime.cc b/src/runtime.cc
index 363d799..c979849 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -593,7 +593,7 @@
}
if (JSObject::cast(*boilerplate)->elements()->map() ==
isolate->heap()->fixed_cow_array_map()) {
- COUNTERS->cow_arrays_created_runtime()->Increment();
+ isolate->counters()->cow_arrays_created_runtime()->Increment();
}
return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
}
@@ -1811,13 +1811,13 @@
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, holder, 0);
- InstallBuiltin(isolate, holder, "pop", Builtins::ArrayPop);
- InstallBuiltin(isolate, holder, "push", Builtins::ArrayPush);
- InstallBuiltin(isolate, holder, "shift", Builtins::ArrayShift);
- InstallBuiltin(isolate, holder, "unshift", Builtins::ArrayUnshift);
- InstallBuiltin(isolate, holder, "slice", Builtins::ArraySlice);
- InstallBuiltin(isolate, holder, "splice", Builtins::ArraySplice);
- InstallBuiltin(isolate, holder, "concat", Builtins::ArrayConcat);
+ InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
+ InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
+ InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
+ InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
+ InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
+ InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
+ InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
return *holder;
}
@@ -5230,8 +5230,9 @@
int final_length = static_cast<int>(
write_cursor - reinterpret_cast<Char*>(
new_string->address() + SeqAsciiString::kHeaderSize));
- isolate->heap()->new_space()->ShrinkStringAtAllocationBoundary<StringType>(
- new_string, final_length);
+ isolate->heap()->new_space()->
+ template ShrinkStringAtAllocationBoundary<StringType>(
+ new_string, final_length);
return new_string;
}
@@ -7650,8 +7651,7 @@
}
StackCheckStub check_stub;
Handle<Code> check_code = check_stub.GetCode();
- Handle<Code> replacement_code(
- isolate->builtins()->builtin(Builtins::OnStackReplacement));
+ Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
Deoptimizer::RevertStackCheckCode(*unoptimized,
*check_code,
*replacement_code);
@@ -9308,6 +9308,7 @@
}
case INTERCEPTOR:
case MAP_TRANSITION:
+ case EXTERNAL_ARRAY_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
return heap->undefined_value();
@@ -12217,16 +12218,17 @@
void Runtime::PerformGC(Object* result) {
+ Isolate* isolate = Isolate::Current();
Failure* failure = Failure::cast(result);
if (failure->IsRetryAfterGC()) {
// Try to do a garbage collection; ignore it if it fails. The C
// entry stub will throw an out-of-memory exception in that case.
- HEAP->CollectGarbage(failure->allocation_space());
+ isolate->heap()->CollectGarbage(failure->allocation_space());
} else {
// Handle last resort GC and make sure to allow future allocations
// to grow the heap without causing GCs (if possible).
- COUNTERS->gc_last_resort_from_js()->Increment();
- HEAP->CollectAllGarbage(false);
+ isolate->counters()->gc_last_resort_from_js()->Increment();
+ isolate->heap()->CollectAllGarbage(false);
}
}
diff --git a/src/serialize.cc b/src/serialize.cc
index 260abd8..12e9613 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -196,7 +196,7 @@
#define DEF_ENTRY_C(name, ignored) \
{ BUILTIN, \
- Builtins::name, \
+ Builtins::k##name, \
"Builtins::" #name },
#define DEF_ENTRY_A(name, kind, state, extra) DEF_ENTRY_C(name, ignored)
diff --git a/src/small-pointer-list.h b/src/small-pointer-list.h
new file mode 100644
index 0000000..6291d9e
--- /dev/null
+++ b/src/small-pointer-list.h
@@ -0,0 +1,163 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_SMALL_POINTER_LIST_H_
+#define V8_SMALL_POINTER_LIST_H_
+
+#include "checks.h"
+#include "v8globals.h"
+#include "zone.h"
+
+namespace v8 {
+namespace internal {
+
+// SmallPointerList is a list optimized for storing no or just a
+// single value. When more values are given it falls back to ZoneList.
+//
+// The interface tries to be as close to List from list.h as possible.
+template <typename T>
+class SmallPointerList {
+ public:
+ SmallPointerList() : data_(kEmptyTag) {}
+
+ bool is_empty() const { return length() == 0; }
+
+ int length() const {
+ if ((data_ & kTagMask) == kEmptyTag) return 0;
+ if ((data_ & kTagMask) == kSingletonTag) return 1;
+ return list()->length();
+ }
+
+ void Add(T* pointer) {
+ ASSERT(IsAligned(reinterpret_cast<intptr_t>(pointer), kPointerAlignment));
+ if ((data_ & kTagMask) == kEmptyTag) {
+ data_ = reinterpret_cast<intptr_t>(pointer) | kSingletonTag;
+ return;
+ }
+ if ((data_ & kTagMask) == kSingletonTag) {
+ PointerList* list = new PointerList(2);
+ list->Add(single_value());
+ list->Add(pointer);
+ ASSERT(IsAligned(reinterpret_cast<intptr_t>(list), kPointerAlignment));
+ data_ = reinterpret_cast<intptr_t>(list) | kListTag;
+ return;
+ }
+ list()->Add(pointer);
+ }
+
+ // Note: returns T* and not T*& (unlike List from list.h).
+ // This makes the implementation simpler and more const correct.
+ T* at(int i) const {
+ ASSERT((data_ & kTagMask) != kEmptyTag);
+ if ((data_ & kTagMask) == kSingletonTag) {
+ ASSERT(i == 0);
+ return single_value();
+ }
+ return list()->at(i);
+ }
+
+ // See the note above.
+ T* operator[](int i) const { return at(i); }
+
+ // Remove the given element from the list (if present).
+ void RemoveElement(T* pointer) {
+ if ((data_ & kTagMask) == kEmptyTag) return;
+ if ((data_ & kTagMask) == kSingletonTag) {
+ if (pointer == single_value()) {
+ data_ = kEmptyTag;
+ }
+ return;
+ }
+ list()->RemoveElement(pointer);
+ }
+
+ T* RemoveLast() {
+ ASSERT((data_ & kTagMask) != kEmptyTag);
+ if ((data_ & kTagMask) == kSingletonTag) {
+ T* result = single_value();
+ data_ = kEmptyTag;
+ return result;
+ }
+ return list()->RemoveLast();
+ }
+
+ void Rewind(int pos) {
+ if ((data_ & kTagMask) == kEmptyTag) {
+ ASSERT(pos == 0);
+ return;
+ }
+ if ((data_ & kTagMask) == kSingletonTag) {
+ ASSERT(pos == 0 || pos == 1);
+ if (pos == 0) {
+ data_ = kEmptyTag;
+ }
+ return;
+ }
+ list()->Rewind(pos);
+ }
+
+ int CountOccurrences(T* pointer, int start, int end) const {
+ if ((data_ & kTagMask) == kEmptyTag) return 0;
+ if ((data_ & kTagMask) == kSingletonTag) {
+ if (start == 0 && end >= 0) {
+ return (single_value() == pointer) ? 1 : 0;
+ }
+ return 0;
+ }
+ return list()->CountOccurrences(pointer, start, end);
+ }
+
+ private:
+ typedef ZoneList<T*> PointerList;
+
+ static const intptr_t kEmptyTag = 1;
+ static const intptr_t kSingletonTag = 0;
+ static const intptr_t kListTag = 2;
+ static const intptr_t kTagMask = 3;
+ static const intptr_t kValueMask = ~kTagMask;
+
+ STATIC_ASSERT(kTagMask + 1 <= kPointerAlignment);
+
+ T* single_value() const {
+ ASSERT((data_ & kTagMask) == kSingletonTag);
+ STATIC_ASSERT(kSingletonTag == 0);
+ return reinterpret_cast<T*>(data_);
+ }
+
+ PointerList* list() const {
+ ASSERT((data_ & kTagMask) == kListTag);
+ return reinterpret_cast<PointerList*>(data_ & kValueMask);
+ }
+
+ intptr_t data_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmallPointerList);
+};
+
+} } // namespace v8::internal
+
+#endif // V8_SMALL_POINTER_LIST_H_
diff --git a/src/spaces.cc b/src/spaces.cc
index ca76189..20700e1 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -393,7 +393,7 @@
#ifdef DEBUG
ZapBlock(reinterpret_cast<Address>(mem), alloced);
#endif
- COUNTERS->memory_allocated()->Increment(alloced);
+ isolate_->counters()->memory_allocated()->Increment(alloced);
return mem;
}
@@ -409,7 +409,7 @@
} else {
OS::Free(mem, length);
}
- COUNTERS->memory_allocated()->Decrement(static_cast<int>(length));
+ isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(length));
size_ -= static_cast<int>(length);
if (executable == EXECUTABLE) size_executable_ -= static_cast<int>(length);
@@ -537,7 +537,7 @@
#ifdef DEBUG
ZapBlock(start, size);
#endif
- COUNTERS->memory_allocated()->Increment(static_cast<int>(size));
+ isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size));
// So long as we correctly overestimated the number of chunks we should not
// run out of chunk ids.
@@ -561,7 +561,7 @@
#ifdef DEBUG
ZapBlock(start, size);
#endif
- COUNTERS->memory_allocated()->Increment(static_cast<int>(size));
+ isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size));
return true;
}
@@ -574,7 +574,7 @@
ASSERT(InInitialChunk(start + size - 1));
if (!initial_chunk_->Uncommit(start, size)) return false;
- COUNTERS->memory_allocated()->Decrement(static_cast<int>(size));
+ isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size));
return true;
}
@@ -675,7 +675,8 @@
// TODO(1240712): VirtualMemory::Uncommit has a return value which
// is ignored here.
initial_chunk_->Uncommit(c.address(), c.size());
- COUNTERS->memory_allocated()->Decrement(static_cast<int>(c.size()));
+ Counters* counters = isolate_->counters();
+ counters->memory_allocated()->Decrement(static_cast<int>(c.size()));
} else {
LOG(isolate_, DeleteEvent("PagedChunk", c.address()));
ObjectSpace space = static_cast<ObjectSpace>(1 << c.owner_identity());
@@ -2753,7 +2754,7 @@
LargeObjectChunk* chunk = reinterpret_cast<LargeObjectChunk*>(mem);
chunk->size_ = size;
Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize));
- page->heap_ = Isolate::Current()->heap();
+ page->heap_ = isolate->heap();
return chunk;
}
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 0e78af4..cd198e2 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -84,7 +84,7 @@
// If the primary entry has useful data in it, we retire it to the
// secondary cache before overwriting it.
- if (hit != isolate_->builtins()->builtin(Builtins::Illegal)) {
+ if (hit != isolate_->builtins()->builtin(Builtins::kIllegal)) {
Code::Flags primary_flags = Code::RemoveTypeFromFlags(hit->flags());
int secondary_offset =
SecondaryOffset(primary->key, primary_flags, primary_offset);
@@ -245,7 +245,7 @@
MaybeObject* StubCache::ComputeLoadNormal() {
- return isolate_->builtins()->builtin(Builtins::LoadIC_Normal);
+ return isolate_->builtins()->builtin(Builtins::kLoadIC_Normal);
}
@@ -649,7 +649,7 @@
}
Object* result;
{ MaybeObject* maybe_result =
- receiver->map()->UpdateCodeCache(name, Code::cast(code));
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
if (!maybe_result->ToObject(&result)) return maybe_result;
}
}
@@ -659,8 +659,8 @@
MaybeObject* StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
return isolate_->builtins()->builtin((strict_mode == kStrictMode)
- ? Builtins::StoreIC_Normal_Strict
- : Builtins::StoreIC_Normal);
+ ? Builtins::kStoreIC_Normal_Strict
+ : Builtins::kStoreIC_Normal);
}
@@ -1221,12 +1221,12 @@
for (int i = 0; i < kPrimaryTableSize; i++) {
primary_[i].key = isolate_->heap()->empty_string();
primary_[i].value = isolate_->builtins()->builtin(
- Builtins::Illegal);
+ Builtins::kIllegal);
}
for (int j = 0; j < kSecondaryTableSize; j++) {
secondary_[j].key = isolate_->heap()->empty_string();
secondary_[j].value = isolate_->builtins()->builtin(
- Builtins::Illegal);
+ Builtins::kIllegal);
}
}
@@ -1500,7 +1500,7 @@
GetCodeWithFlags(flags, "CompileCallInitialize");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- COUNTERS->call_initialize_stubs()->Increment();
+ isolate()->counters()->call_initialize_stubs()->Increment();
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(),
@@ -1527,7 +1527,7 @@
GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- COUNTERS->call_premonomorphic_stubs()->Increment();
+ isolate()->counters()->call_premonomorphic_stubs()->Increment();
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(),
@@ -1551,7 +1551,7 @@
{ MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- COUNTERS->call_normal_stubs()->Increment();
+ isolate()->counters()->call_normal_stubs()->Increment();
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(),
@@ -1576,7 +1576,7 @@
GetCodeWithFlags(flags, "CompileCallMegamorphic");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- COUNTERS->call_megamorphic_stubs()->Increment();
+ isolate()->counters()->call_megamorphic_stubs()->Increment();
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(),
@@ -1600,7 +1600,7 @@
{ MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- COUNTERS->call_megamorphic_stubs()->Increment();
+ isolate()->counters()->call_megamorphic_stubs()->Increment();
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(),
diff --git a/src/type-info.cc b/src/type-info.cc
index 7367390..78f693c 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -335,7 +335,7 @@
Handle<Object> object = GetInfo(position);
if (object->IsUndefined() || object->IsSmi()) return NULL;
- if (*object == isolate->builtins()->builtin(Builtins::StoreIC_GlobalProxy)) {
+ if (*object == isolate->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
// TODO(fschneider): We could collect the maps and signal that
// we need a generic store (or load) here.
ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC);
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 27c2a96..04482e8 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -207,8 +207,6 @@
SC(memcopy_noxmm, V8.MemCopyNoXMM) \
SC(enum_cache_hits, V8.EnumCacheHits) \
SC(enum_cache_misses, V8.EnumCacheMisses) \
- SC(reloc_info_count, V8.RelocInfoCount) \
- SC(reloc_info_size, V8.RelocInfoSize) \
SC(zone_segment_bytes, V8.ZoneSegmentBytes) \
SC(compute_entry_frame, V8.ComputeEntryFrame) \
SC(generic_binary_stub_calls, V8.GenericBinaryStubCalls) \
@@ -311,8 +309,6 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(Counters);
};
-#define COUNTERS Isolate::Current()->counters()
-
} } // namespace v8::internal
#endif // V8_V8_COUNTERS_H_
diff --git a/src/v8globals.h b/src/v8globals.h
index 0933acf..7ff464a 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -318,14 +318,15 @@
// Must fit in the BitField PropertyDetails::TypeField.
// A copy of this is in mirror-debugger.js.
enum PropertyType {
- NORMAL = 0, // only in slow mode
- FIELD = 1, // only in fast mode
- CONSTANT_FUNCTION = 2, // only in fast mode
- CALLBACKS = 3,
- INTERCEPTOR = 4, // only in lookup results, not in descriptors.
- MAP_TRANSITION = 5, // only in fast mode
- CONSTANT_TRANSITION = 6, // only in fast mode
- NULL_DESCRIPTOR = 7, // only in fast mode
+ NORMAL = 0, // only in slow mode
+ FIELD = 1, // only in fast mode
+ CONSTANT_FUNCTION = 2, // only in fast mode
+ CALLBACKS = 3,
+ INTERCEPTOR = 4, // only in lookup results, not in descriptors.
+ MAP_TRANSITION = 5, // only in fast mode
+ EXTERNAL_ARRAY_TRANSITION = 6,
+ CONSTANT_TRANSITION = 7, // only in fast mode
+ NULL_DESCRIPTOR = 8, // only in fast mode
// All properties before MAP_TRANSITION are real.
FIRST_PHANTOM_PROPERTY_TYPE = MAP_TRANSITION,
// There are no IC stubs for NULL_DESCRIPTORS. Therefore,
diff --git a/src/version.cc b/src/version.cc
index d1c85f3..e90c1cb 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,9 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 2
-#define BUILD_NUMBER 4
-#define PATCH_LEVEL 2
+#define BUILD_NUMBER 5
+#define PATCH_LEVEL 0
+
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 9a031ee..0744b8a 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -415,8 +415,6 @@
desc->reloc_size =
static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
desc->origin = this;
-
- COUNTERS->reloc_info_size()->Increment(desc->reloc_size);
}
@@ -946,6 +944,12 @@
emit(0xF8);
}
+void Assembler::cld() {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit(0xFC);
+}
+
void Assembler::cdq() {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 5d91436..52aca63 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -1137,6 +1137,7 @@
// Miscellaneous
void clc();
+ void cld();
void cpuid();
void hlt();
void int3();
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 3db449c..21d3e54 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -98,8 +98,8 @@
// Set expected number of arguments to zero (not changing rax).
__ movq(rbx, Immediate(0));
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
- __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
}
@@ -339,8 +339,8 @@
// Call the function.
if (is_api_function) {
__ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
- Handle<Code> code = Handle<Code>(masm->isolate()->builtins()->builtin(
- Builtins::HandleApiCallConstruct));
+ Handle<Code> code =
+ masm->isolate()->builtins()->HandleApiCallConstruct();
ParameterCount expected(0);
__ InvokeCode(code, expected, expected,
RelocInfo::CODE_TARGET, CALL_FUNCTION);
@@ -379,7 +379,8 @@
SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
__ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
__ push(rcx);
- __ IncrementCounter(COUNTERS->constructed_objects(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->constructed_objects(), 1);
__ ret(0);
}
@@ -492,8 +493,8 @@
// Invoke the code.
if (is_construct) {
// Expects rdi to hold function pointer.
- __ Call(Handle<Code>(masm->isolate()->builtins()->builtin(
- Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
+ __ Call(masm->isolate()->builtins()->JSConstructCall(),
+ RelocInfo::CODE_TARGET);
} else {
ParameterCount actual(rax);
// Function must be in rdi.
@@ -733,8 +734,8 @@
__ j(not_zero, &function);
__ Set(rbx, 0);
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
- __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
__ bind(&function);
}
@@ -748,8 +749,8 @@
__ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
__ cmpq(rax, rbx);
__ j(not_equal,
- Handle<Code>(masm->isolate()->builtins()->builtin(
- ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
ParameterCount expected(0);
__ InvokeCode(rdx, expected, expected, JUMP_FUNCTION);
@@ -863,8 +864,8 @@
__ movq(rdx, Operand(rbp, kArgumentsOffset)); // load arguments
// Use inline caching to speed up access to arguments.
- Handle<Code> ic(masm->isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic =
+ masm->isolate()->builtins()->KeyedLoadIC_Initialize();
__ Call(ic, RelocInfo::CODE_TARGET);
// It is important that we do not have a test instruction after the
// call. A test instruction after the call is used to indicate that
@@ -1138,7 +1139,8 @@
r8,
kPreallocatedArrayElements,
call_generic_code);
- __ IncrementCounter(COUNTERS->array_function_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->array_function_native(), 1);
__ movq(rax, rbx);
__ ret(kPointerSize);
@@ -1169,7 +1171,7 @@
r9,
true,
call_generic_code);
- __ IncrementCounter(COUNTERS->array_function_native(), 1);
+ __ IncrementCounter(counters->array_function_native(), 1);
__ movq(rax, rbx);
__ ret(2 * kPointerSize);
@@ -1191,7 +1193,7 @@
r9,
false,
call_generic_code);
- __ IncrementCounter(COUNTERS->array_function_native(), 1);
+ __ IncrementCounter(counters->array_function_native(), 1);
// rax: argc
// rbx: JSArray
@@ -1265,9 +1267,8 @@
// Jump to the generic array code in case the specialized code cannot handle
// the construction.
__ bind(&generic_array_code);
- Code* code =
- masm->isolate()->builtins()->builtin(Builtins::ArrayCodeGeneric);
- Handle<Code> array_code(code);
+ Handle<Code> array_code =
+ masm->isolate()->builtins()->ArrayCodeGeneric();
__ Jump(array_code, RelocInfo::CODE_TARGET);
}
@@ -1300,9 +1301,8 @@
// Jump to the generic construct code in case the specialized code cannot
// handle the construction.
__ bind(&generic_constructor);
- Code* code =
- masm->isolate()->builtins()->builtin(Builtins::JSConstructStubGeneric);
- Handle<Code> generic_construct_stub(code);
+ Handle<Code> generic_construct_stub =
+ masm->isolate()->builtins()->JSConstructStubGeneric();
__ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
}
@@ -1356,7 +1356,8 @@
// -----------------------------------
Label invoke, dont_adapt_arguments;
- __ IncrementCounter(COUNTERS->arguments_adaptors(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->arguments_adaptors(), 1);
Label enough, too_few;
__ cmpq(rax, rbx);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 9196e3a..e6f4696 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -359,7 +359,8 @@
// Update flags to indicate that arguments are in registers.
SetArgsInRegisters();
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
}
// Call the stub.
@@ -395,7 +396,8 @@
// Update flags to indicate that arguments are in registers.
SetArgsInRegisters();
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
}
// Call the stub.
@@ -430,7 +432,8 @@
}
// Update flags to indicate that arguments are in registers.
SetArgsInRegisters();
- __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
}
// Call the stub.
@@ -2599,7 +2602,8 @@
// rcx: encoding of subject string (1 if ascii 0 if two_byte);
// r11: code
// All checks done. Now push arguments for native regexp code.
- __ IncrementCounter(COUNTERS->regexp_entry_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->regexp_entry_native(), 1);
// Isolates: note we add an additional parameter here (isolate pointer).
static const int kRegExpExecuteArguments = 8;
@@ -2951,7 +2955,8 @@
index,
times_1,
FixedArray::kHeaderSize + kPointerSize));
- __ IncrementCounter(COUNTERS->number_to_string_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->number_to_string_native(), 1);
}
@@ -3327,8 +3332,8 @@
__ Set(rax, argc_);
__ Set(rbx, 0);
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
- Handle<Code> adaptor(Isolate::Current()->builtins()->builtin(
- Builtins::ArgumentsAdaptorTrampoline));
+ Handle<Code> adaptor =
+ Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline();
__ Jump(adaptor, RelocInfo::CODE_TARGET);
}
@@ -3651,11 +3656,11 @@
// directly in the code, because the builtin stubs may not have been
// generated yet at the time this code is generated.
if (is_construct) {
- ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline,
+ ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
isolate);
__ Load(rax, construct_entry);
} else {
- ExternalReference entry(Builtins::JSEntryTrampoline, isolate);
+ ExternalReference entry(Builtins::kJSEntryTrampoline, isolate);
__ Load(rax, entry);
}
__ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
@@ -4173,7 +4178,8 @@
__ SmiTest(rcx);
__ j(not_zero, &second_not_zero_length);
// Second string is empty, result is first string which is already in rax.
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
__ bind(&second_not_zero_length);
__ movq(rbx, FieldOperand(rax, String::kLengthOffset));
@@ -4181,7 +4187,7 @@
__ j(not_zero, &both_not_zero_length);
// First string is empty, result is second string which is in rdx.
__ movq(rax, rdx);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
// Both strings are non-empty.
@@ -4225,7 +4231,7 @@
Label make_two_character_string, make_flat_ascii_string;
StringHelper::GenerateTwoCharacterSymbolTableProbe(
masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
__ bind(&make_two_character_string);
@@ -4265,7 +4271,7 @@
__ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax);
__ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx);
__ movq(rax, rcx);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
__ bind(&non_ascii);
// At least one of the strings is two-byte. Check whether it happens
@@ -4339,7 +4345,7 @@
// rdi: length of second argument
StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, true);
__ movq(rax, rbx);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
// Handle creating a flat two byte result.
@@ -4376,7 +4382,7 @@
// rdi: length of second argument
StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, false);
__ movq(rax, rbx);
- __ IncrementCounter(COUNTERS->string_add_native(), 1);
+ __ IncrementCounter(counters->string_add_native(), 1);
__ ret(2 * kPointerSize);
// Just jump to runtime to add the two strings.
@@ -4791,7 +4797,8 @@
// rsi: character of sub string start
StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
__ movq(rsi, rdx); // Restore rsi.
- __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->sub_string_native(), 1);
__ ret(kArgumentsSize);
__ bind(&non_ascii_flat);
@@ -4828,7 +4835,7 @@
__ movq(rsi, rdx); // Restore esi.
__ bind(&return_rax);
- __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+ __ IncrementCounter(counters->sub_string_native(), 1);
__ ret(kArgumentsSize);
// Just jump to runtime to create the sub string.
@@ -4942,7 +4949,8 @@
__ cmpq(rdx, rax);
__ j(not_equal, ¬_same);
__ Move(rax, Smi::FromInt(EQUAL));
- __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->string_compare_native(), 1);
__ ret(2 * kPointerSize);
__ bind(¬_same);
@@ -4951,7 +4959,7 @@
__ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime);
// Inline comparison of ascii strings.
- __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+ __ IncrementCounter(counters->string_compare_native(), 1);
// Drop arguments from the stack
__ pop(rcx);
__ addq(rsp, Immediate(2 * kPointerSize));
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 33c5752..6f34cf7 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -2561,8 +2561,7 @@
__ j(not_equal, &build_args);
__ movq(rcx, FieldOperand(rax, JSFunction::kCodeEntryOffset));
__ subq(rcx, Immediate(Code::kHeaderSize - kHeapObjectTag));
- Handle<Code> apply_code(Isolate::Current()->builtins()->builtin(
- Builtins::FunctionApply));
+ Handle<Code> apply_code = Isolate::Current()->builtins()->FunctionApply();
__ Cmp(rcx, apply_code);
__ j(not_equal, &build_args);
@@ -4982,7 +4981,8 @@
FastCloneShallowArrayStub stub(
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
clone = frame_->CallStub(&stub, 3);
- __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->cow_arrays_created_stub(), 1);
} else if (node->depth() > 1) {
clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
} else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
@@ -7998,8 +7998,7 @@
__ movq(rax, receiver_);
}
__ Move(rcx, name_);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = Isolate::Current()->builtins()->LoadIC_Initialize();
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a test rax instruction to indicate
// that the inobject property case was inlined.
@@ -8011,7 +8010,8 @@
// Here we use masm_-> instead of the __ macro because this is the
// instruction that gets patched and coverage code gets in the way.
masm_->testl(rax, Immediate(-delta_to_patch_site));
- __ IncrementCounter(COUNTERS->named_load_inline_miss(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->named_load_inline_miss(), 1);
if (!dst_.is(rax)) __ movq(dst_, rax);
}
@@ -8064,8 +8064,7 @@
// it in the IC initialization code and patch the movq instruction.
// This means that we cannot allow test instructions after calls to
// KeyedLoadIC stubs in other places.
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = Isolate::Current()->builtins()->KeyedLoadIC_Initialize();
__ Call(ic, RelocInfo::CODE_TARGET);
// The delta from the start of the map-compare instruction to the
// test instruction. We use masm_-> directly here instead of the __
@@ -8079,7 +8078,8 @@
// 7-byte NOP with non-zero immediate (0f 1f 80 xxxxxxxx) which won't
// be generated normally.
masm_->testl(rax, Immediate(-delta_to_patch_site));
- __ IncrementCounter(COUNTERS->keyed_load_inline_miss(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_inline_miss(), 1);
if (!dst_.is(rax)) __ movq(dst_, rax);
}
@@ -8112,7 +8112,8 @@
void DeferredReferenceSetKeyedValue::Generate() {
- __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_store_inline_miss(), 1);
// Move value, receiver, and key to registers rax, rdx, and rcx, as
// the IC stub expects.
// Move value to rax, using xchg if the receiver or key is in rax.
@@ -8160,8 +8161,8 @@
// Call the IC stub.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ (strict_mode_ == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+ : Builtins::kKeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The delta from the start of the map-compare instructions (initial movq)
// to the test instruction. We use masm_-> directly here instead of the
@@ -8247,7 +8248,8 @@
int offset = kMaxInt;
masm()->movq(result.reg(), FieldOperand(receiver.reg(), offset));
- __ IncrementCounter(COUNTERS->named_load_inline(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->named_load_inline(), 1);
deferred->BindExit();
}
ASSERT(frame()->height() == original_height - 1);
@@ -8454,7 +8456,8 @@
result = elements;
__ CompareRoot(result.reg(), Heap::kTheHoleValueRootIndex);
deferred->Branch(equal);
- __ IncrementCounter(COUNTERS->keyed_load_inline(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_inline(), 1);
deferred->BindExit();
} else {
@@ -8565,7 +8568,8 @@
index.scale,
FixedArray::kHeaderSize),
result.reg());
- __ IncrementCounter(COUNTERS->keyed_store_inline(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_store_inline(), 1);
deferred->BindExit();
} else {
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index 63067bd..c58d5ea 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -101,6 +101,11 @@
};
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+ // TODO(1276): Implement.
+}
+
+
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
HandleScope scope;
AssertNoAllocation no_allocation;
@@ -187,7 +192,7 @@
// Add the deoptimizing code to the list.
DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
- DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
+ DeoptimizerData* data = code->GetIsolate()->deoptimizer_data();
node->set_next(data->deoptimizing_code_list_);
data->deoptimizing_code_list_ = node;
@@ -389,8 +394,8 @@
optimized_code_->entry() + pc_offset);
output_[0]->SetPc(pc);
}
- Code* continuation = Isolate::Current()->builtins()->builtin(
- Builtins::NotifyOSR);
+ Code* continuation =
+ function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
output_[0]->SetContinuation(
reinterpret_cast<intptr_t>(continuation->entry()));
@@ -562,9 +567,8 @@
// Set the continuation for the topmost frame.
if (is_topmost) {
Code* continuation = (bailout_type_ == EAGER)
- ? Isolate::Current()->builtins()->builtin(Builtins::NotifyDeoptimized)
- : Isolate::Current()->builtins()->builtin(
- Builtins::NotifyLazyDeoptimized);
+ ? isolate_->builtins()->builtin(Builtins::kNotifyDeoptimized)
+ : isolate_->builtins()->builtin(Builtins::kNotifyLazyDeoptimized);
output_frame->SetContinuation(
reinterpret_cast<intptr_t>(continuation->entry()));
}
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 2253596..90afd85 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -740,9 +740,9 @@
prop->key()->AsLiteral()->handle()->IsSmi());
__ Move(rcx, prop->key()->AsLiteral()->handle());
- Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
- ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
}
@@ -1121,8 +1121,7 @@
// load IC call.
__ movq(rax, GlobalObjectOperand());
__ Move(rcx, slot->var()->name());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
@@ -1205,8 +1204,8 @@
ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
slow));
__ Move(rax, key_literal->handle());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic =
+ isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
__ jmp(done);
}
@@ -1229,8 +1228,7 @@
// object on the stack.
__ Move(rcx, var->name());
__ movq(rax, GlobalObjectOperand());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
context()->Plug(rax);
@@ -1293,8 +1291,7 @@
__ Move(rax, key_literal->handle());
// Do a keyed property load.
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
context()->Plug(rax);
}
@@ -1405,8 +1402,7 @@
__ Move(rcx, key->handle());
__ movq(rdx, Operand(rsp, 0));
if (property->emit_store()) {
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::StoreIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(key->id(), NO_REGISTERS);
}
@@ -1650,16 +1646,14 @@
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
__ Move(rcx, key->handle());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
}
@@ -1765,9 +1759,9 @@
__ movq(rdx, rax);
__ pop(rax); // Restore value.
__ Move(rcx, prop->key()->AsLiteral()->handle());
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
break;
}
@@ -1788,9 +1782,9 @@
__ pop(rdx);
}
__ pop(rax); // Restore value.
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
break;
}
@@ -1814,9 +1808,9 @@
// rcx, and the global object on the stack.
__ Move(rcx, var->name());
__ movq(rdx, GlobalObjectOperand());
- Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
- ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
} else if (op == Token::INIT_CONST) {
@@ -1917,9 +1911,9 @@
} else {
__ pop(rdx);
}
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case.
@@ -1957,9 +1951,9 @@
}
// Record source code position before IC call.
SetSourcePosition(expr->position());
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// If the assignment ends an initialization block, revert to fast case.
@@ -2238,8 +2232,7 @@
// Record source code position for IC call.
SetSourcePosition(prop->position());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
// Push result (function).
__ push(rax);
@@ -2307,8 +2300,8 @@
__ Set(rax, arg_count);
__ movq(rdi, Operand(rsp, arg_count * kPointerSize));
- Handle<Code> construct_builtin(isolate()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Handle<Code> construct_builtin =
+ isolate()->builtins()->JSConstructCall();
__ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
context()->Plug(rax);
}
@@ -3231,7 +3224,288 @@
void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
- context()->Plug(Heap::kUndefinedValueRootIndex);
+ Label bailout, return_result, done, one_char_separator, long_separator,
+ non_trivial_array, not_size_one_array, loop,
+ loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry;
+ ASSERT(args->length() == 2);
+ // We will leave the separator on the stack until the end of the function.
+ VisitForStackValue(args->at(1));
+ // Load this to rax (= array)
+ VisitForAccumulatorValue(args->at(0));
+ // All aliases of the same register have disjoint lifetimes.
+ Register array = rax;
+ Register elements = no_reg; // Will be rax.
+
+ Register index = rdx;
+
+ Register string_length = rcx;
+
+ Register string = rsi;
+
+ Register scratch = rbx;
+
+ Register array_length = rdi;
+ Register result_pos = no_reg; // Will be rdi.
+
+ Operand separator_operand = Operand(rsp, 2 * kPointerSize);
+ Operand result_operand = Operand(rsp, 1 * kPointerSize);
+ Operand array_length_operand = Operand(rsp, 0 * kPointerSize);
+ // Separator operand is already pushed. Make room for the two
+ // other stack fields, and clear the direction flag in anticipation
+ // of calling CopyBytes.
+ __ subq(rsp, Immediate(2 * kPointerSize));
+ __ cld();
+ // Check that the array is a JSArray
+ __ JumpIfSmi(array, &bailout);
+ __ CmpObjectType(array, JS_ARRAY_TYPE, scratch);
+ __ j(not_equal, &bailout);
+
+ // Check that the array has fast elements.
+ __ testb(FieldOperand(scratch, Map::kBitField2Offset),
+ Immediate(1 << Map::kHasFastElements));
+ __ j(zero, &bailout);
+
+ // Array has fast elements, so its length must be a smi.
+ // If the array has length zero, return the empty string.
+ __ movq(array_length, FieldOperand(array, JSArray::kLengthOffset));
+ __ SmiCompare(array_length, Smi::FromInt(0));
+ __ j(not_zero, &non_trivial_array);
+ __ LoadRoot(rax, Heap::kEmptyStringRootIndex);
+ __ jmp(&return_result);
+
+ // Save the array length on the stack.
+ __ bind(&non_trivial_array);
+ __ SmiToInteger32(array_length, array_length);
+ __ movl(array_length_operand, array_length);
+
+ // Save the FixedArray containing array's elements.
+ // End of array's live range.
+ elements = array;
+ __ movq(elements, FieldOperand(array, JSArray::kElementsOffset));
+ array = no_reg;
+
+
+ // Check that all array elements are sequential ASCII strings, and
+ // accumulate the sum of their lengths, as a smi-encoded value.
+ __ Set(index, 0);
+ __ Set(string_length, 0);
+ // Loop condition: while (index < array_length).
+ // Live loop registers: index(int32), array_length(int32), string(String*),
+ // scratch, string_length(int32), elements(FixedArray*).
+ if (FLAG_debug_code) {
+ __ cmpq(index, array_length);
+ __ Assert(below, "No empty arrays here in EmitFastAsciiArrayJoin");
+ }
+ __ bind(&loop);
+ __ movq(string, FieldOperand(elements,
+ index,
+ times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ JumpIfSmi(string, &bailout);
+ __ movq(scratch, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzxbl(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
+ __ andb(scratch, Immediate(
+ kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
+ __ cmpb(scratch, Immediate(kStringTag | kAsciiStringTag | kSeqStringTag));
+ __ j(not_equal, &bailout);
+ __ AddSmiField(string_length,
+ FieldOperand(string, SeqAsciiString::kLengthOffset));
+ __ j(overflow, &bailout);
+ __ incl(index);
+ __ cmpl(index, array_length);
+ __ j(less, &loop);
+
+ // Live registers:
+ // string_length: Sum of string lengths.
+ // elements: FixedArray of strings.
+ // index: Array length.
+ // array_length: Array length.
+
+ // If array_length is 1, return elements[0], a string.
+ __ cmpl(array_length, Immediate(1));
+ __ j(not_equal, ¬_size_one_array);
+ __ movq(rax, FieldOperand(elements, FixedArray::kHeaderSize));
+ __ jmp(&return_result);
+
+ __ bind(¬_size_one_array);
+
+ // End of array_length live range.
+ result_pos = array_length;
+ array_length = no_reg;
+
+ // Live registers:
+ // string_length: Sum of string lengths.
+ // elements: FixedArray of strings.
+ // index: Array length.
+
+ // Check that the separator is a sequential ASCII string.
+ __ movq(string, separator_operand);
+ __ JumpIfSmi(string, &bailout);
+ __ movq(scratch, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzxbl(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
+ __ andb(scratch, Immediate(
+ kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
+ __ cmpb(scratch, Immediate(kStringTag | kAsciiStringTag | kSeqStringTag));
+ __ j(not_equal, &bailout);
+
+ // Live registers:
+ // string_length: Sum of string lengths.
+ // elements: FixedArray of strings.
+ // index: Array length.
+ // string: Separator string.
+
+ // Add (separator length times (array_length - 1)) to string_length.
+ __ SmiToInteger32(scratch,
+ FieldOperand(string, SeqAsciiString::kLengthOffset));
+ __ decl(index);
+ __ imull(scratch, index);
+ __ j(overflow, &bailout);
+ __ addl(string_length, scratch);
+ __ j(overflow, &bailout);
+
+ // Live registers and stack values:
+ // string_length: Total length of result string.
+ // elements: FixedArray of strings.
+ __ AllocateAsciiString(result_pos, string_length, scratch,
+ index, string, &bailout);
+ __ movq(result_operand, result_pos);
+ __ lea(result_pos, FieldOperand(result_pos, SeqAsciiString::kHeaderSize));
+
+ __ movq(string, separator_operand);
+ __ SmiCompare(FieldOperand(string, SeqAsciiString::kLengthOffset),
+ Smi::FromInt(1));
+ __ j(equal, &one_char_separator);
+ __ j(greater, &long_separator);
+
+
+ // Empty separator case:
+ __ Set(index, 0);
+ __ movl(scratch, array_length_operand);
+ __ jmp(&loop_1_condition);
+ // Loop condition: while (index < array_length).
+ __ bind(&loop_1);
+ // Each iteration of the loop concatenates one string to the result.
+ // Live values in registers:
+ // index: which element of the elements array we are adding to the result.
+ // result_pos: the position to which we are currently copying characters.
+ // elements: the FixedArray of strings we are joining.
+ // scratch: array length.
+
+ // Get string = array[index].
+ __ movq(string, FieldOperand(elements, index,
+ times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ SmiToInteger32(string_length,
+ FieldOperand(string, String::kLengthOffset));
+ __ lea(string,
+ FieldOperand(string, SeqAsciiString::kHeaderSize));
+ __ CopyBytes(result_pos, string, string_length);
+ __ incl(index);
+ __ bind(&loop_1_condition);
+ __ cmpl(index, scratch);
+ __ j(less, &loop_1); // Loop while (index < array_length).
+ __ jmp(&done);
+
+ // Generic bailout code used from several places.
+ __ bind(&bailout);
+ __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
+ __ jmp(&return_result);
+
+
+ // One-character separator case
+ __ bind(&one_char_separator);
+ // Get the separator ascii character value.
+ // Register "string" holds the separator.
+ __ movzxbl(scratch, FieldOperand(string, SeqAsciiString::kHeaderSize));
+ __ Set(index, 0);
+ // Jump into the loop after the code that copies the separator, so the first
+ // element is not preceded by a separator
+ __ jmp(&loop_2_entry);
+ // Loop condition: while (index < length).
+ __ bind(&loop_2);
+ // Each iteration of the loop concatenates one string to the result.
+ // Live values in registers:
+ // elements: The FixedArray of strings we are joining.
+ // index: which element of the elements array we are adding to the result.
+ // result_pos: the position to which we are currently copying characters.
+ // scratch: Separator character.
+
+ // Copy the separator character to the result.
+ __ movb(Operand(result_pos, 0), scratch);
+ __ incq(result_pos);
+
+ __ bind(&loop_2_entry);
+ // Get string = array[index].
+ __ movq(string, FieldOperand(elements, index,
+ times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ SmiToInteger32(string_length,
+ FieldOperand(string, String::kLengthOffset));
+ __ lea(string,
+ FieldOperand(string, SeqAsciiString::kHeaderSize));
+ __ CopyBytes(result_pos, string, string_length);
+ __ incl(index);
+ __ cmpl(index, array_length_operand);
+ __ j(less, &loop_2); // End while (index < length).
+ __ jmp(&done);
+
+
+ // Long separator case (separator is more than one character).
+ __ bind(&long_separator);
+
+ // Make elements point to end of elements array, and index
+ // count from -array_length to zero, so we don't need to maintain
+ // a loop limit.
+ __ movl(index, array_length_operand);
+ __ lea(elements, FieldOperand(elements, index, times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ neg(index);
+
+ // Replace separator string with pointer to its first character, and
+ // make scratch be its length.
+ __ movq(string, separator_operand);
+ __ SmiToInteger32(scratch,
+ FieldOperand(string, String::kLengthOffset));
+ __ lea(string,
+ FieldOperand(string, SeqAsciiString::kHeaderSize));
+ __ movq(separator_operand, string);
+
+ // Jump into the loop after the code that copies the separator, so the first
+ // element is not preceded by a separator
+ __ jmp(&loop_3_entry);
+ // Loop condition: while (index < length).
+ __ bind(&loop_3);
+ // Each iteration of the loop concatenates one string to the result.
+ // Live values in registers:
+ // index: which element of the elements array we are adding to the result.
+ // result_pos: the position to which we are currently copying characters.
+ // scratch: Separator length.
+ // separator_operand (rsp[0x10]): Address of first char of separator.
+
+ // Copy the separator to the result.
+ __ movq(string, separator_operand);
+ __ movl(string_length, scratch);
+ __ CopyBytes(result_pos, string, string_length, 2);
+
+ __ bind(&loop_3_entry);
+ // Get string = array[index].
+ __ movq(string, Operand(elements, index, times_pointer_size, 0));
+ __ SmiToInteger32(string_length,
+ FieldOperand(string, String::kLengthOffset));
+ __ lea(string,
+ FieldOperand(string, SeqAsciiString::kHeaderSize));
+ __ CopyBytes(result_pos, string, string_length);
+ __ incq(index);
+ __ j(not_equal, &loop_3); // Loop while (index < 0).
+
+ __ bind(&done);
+ __ movq(rax, result_operand);
+
+ __ bind(&return_result);
+ // Drop temp values from the stack, and restore context register.
+ __ addq(rsp, Immediate(3 * kPointerSize));
+ __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+ context()->Plug(rax);
}
@@ -3575,9 +3849,9 @@
case NAMED_PROPERTY: {
__ Move(rcx, prop->key()->AsLiteral()->handle());
__ pop(rdx);
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -3592,9 +3866,9 @@
case KEYED_PROPERTY: {
__ pop(rcx);
__ pop(rdx);
- Handle<Code> ic(isolate()->builtins()->builtin(
- is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = is_strict_mode()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
EmitCallIC(ic, RelocInfo::CODE_TARGET);
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@@ -3619,8 +3893,7 @@
Comment cmnt(masm_, "Global variable");
__ Move(rcx, proxy->name());
__ movq(rax, GlobalObjectOperand());
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
// Use a regular load, not a contextual load, to avoid a reference
// error.
EmitCallIC(ic, RelocInfo::CODE_TARGET);
@@ -3884,18 +4157,19 @@
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
ASSERT(mode == RelocInfo::CODE_TARGET ||
mode == RelocInfo::CODE_TARGET_CONTEXT);
+ Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
- __ IncrementCounter(COUNTERS->named_load_full(), 1);
+ __ IncrementCounter(counters->named_load_full(), 1);
break;
case Code::KEYED_LOAD_IC:
- __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
+ __ IncrementCounter(counters->keyed_load_full(), 1);
break;
case Code::STORE_IC:
- __ IncrementCounter(COUNTERS->named_store_full(), 1);
+ __ IncrementCounter(counters->named_store_full(), 1);
break;
case Code::KEYED_STORE_IC:
- __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
+ __ IncrementCounter(counters->keyed_store_full(), 1);
default:
break;
}
@@ -3927,18 +4201,19 @@
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
+ Counters* counters = isolate()->counters();
switch (ic->kind()) {
case Code::LOAD_IC:
- __ IncrementCounter(COUNTERS->named_load_full(), 1);
+ __ IncrementCounter(counters->named_load_full(), 1);
break;
case Code::KEYED_LOAD_IC:
- __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
+ __ IncrementCounter(counters->keyed_load_full(), 1);
break;
case Code::STORE_IC:
- __ IncrementCounter(COUNTERS->named_store_full(), 1);
+ __ IncrementCounter(counters->named_store_full(), 1);
break;
case Code::KEYED_STORE_IC:
- __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
+ __ IncrementCounter(counters->keyed_store_full(), 1);
default:
break;
}
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 7755493..9180465 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -579,7 +579,8 @@
rax,
NULL,
&slow);
- __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
__ ret(0);
__ bind(&check_number_dictionary);
@@ -601,7 +602,7 @@
// Slow case: Jump to runtime.
// rdx: receiver
// rax: key
- __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
GenerateRuntimeGetProperty(masm);
__ bind(&check_string);
@@ -652,7 +653,7 @@
__ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
__ addq(rcx, rdi);
__ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0));
- __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
__ ret(0);
// Load property array property.
@@ -660,7 +661,7 @@
__ movq(rax, FieldOperand(rdx, JSObject::kPropertiesOffset));
__ movq(rax, FieldOperand(rax, rdi, times_pointer_size,
FixedArray::kHeaderSize));
- __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
__ ret(0);
// Do a quick inline probe of the receiver's dictionary, if it
@@ -675,7 +676,7 @@
GenerateGlobalInstanceTypeCheck(masm, rcx, &slow);
GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax);
- __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1);
+ __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
__ ret(0);
__ bind(&index_string);
@@ -990,10 +991,11 @@
// rsp[(argc + 1) * 8] : argument 0 = receiver
// -----------------------------------
+ Counters* counters = masm->isolate()->counters();
if (id == IC::kCallIC_Miss) {
- __ IncrementCounter(COUNTERS->call_miss(), 1);
+ __ IncrementCounter(counters->call_miss(), 1);
} else {
- __ IncrementCounter(COUNTERS->keyed_call_miss(), 1);
+ __ IncrementCounter(counters->keyed_call_miss(), 1);
}
// Get the receiver of the function from the stack; 1 ~ return address.
@@ -1119,7 +1121,8 @@
GenerateFastArrayLoad(
masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load);
- __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1);
__ bind(&do_call);
// receiver in rdx is not used after this point.
@@ -1137,13 +1140,13 @@
__ SmiToInteger32(rbx, rcx);
// ebx: untagged index
GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi);
- __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
__ jmp(&do_call);
__ bind(&slow_load);
// This branch is taken when calling KeyedCallIC_Miss is neither required
// nor beneficial.
- __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
__ EnterInternalFrame();
__ push(rcx); // save the key
__ push(rdx); // pass the receiver
@@ -1170,11 +1173,11 @@
__ j(not_equal, &lookup_monomorphic_cache);
GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi);
- __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
__ jmp(&do_call);
__ bind(&lookup_monomorphic_cache);
- __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
// Fall through on miss.
@@ -1185,7 +1188,7 @@
// - the value loaded is not a function,
// - there is hope that the runtime will create a monomorphic call stub
// that will get fetched next time.
- __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1);
+ __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
GenerateMiss(masm, argc);
__ bind(&index_string);
@@ -1279,7 +1282,8 @@
// -- rsp[0] : return address
// -----------------------------------
- __ IncrementCounter(COUNTERS->load_miss(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->load_miss(), 1);
__ pop(rbx);
__ push(rax); // receiver
@@ -1424,7 +1428,8 @@
// -- rsp[0] : return address
// -----------------------------------
- __ IncrementCounter(COUNTERS->keyed_load_miss(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_miss(), 1);
__ pop(rbx);
__ push(rdx); // receiver
@@ -1569,11 +1574,12 @@
GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
- __ IncrementCounter(COUNTERS->store_normal_hit(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->store_normal_hit(), 1);
__ ret(0);
__ bind(&miss);
- __ IncrementCounter(COUNTERS->store_normal_miss(), 1);
+ __ IncrementCounter(counters->store_normal_miss(), 1);
GenerateMiss(masm);
}
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 5af2795..a3609fd 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -43,12 +43,10 @@
public:
SafepointGenerator(LCodeGen* codegen,
LPointerMap* pointers,
- int deoptimization_index,
- bool ensure_reloc_space = false)
+ int deoptimization_index)
: codegen_(codegen),
pointers_(pointers),
- deoptimization_index_(deoptimization_index),
- ensure_reloc_space_(ensure_reloc_space) { }
+ deoptimization_index_(deoptimization_index) { }
virtual ~SafepointGenerator() { }
virtual void BeforeCall(int call_size) {
@@ -67,9 +65,7 @@
virtual void AfterCall() {
// Ensure that we have enough space in the reloc info to patch
// this with calls when doing deoptimization.
- if (ensure_reloc_space_) {
- codegen_->masm()->RecordComment(RelocInfo::kFillerCommentString, true);
- }
+ codegen_->masm()->RecordComment(RelocInfo::kFillerCommentString, true);
codegen_->RecordSafepoint(pointers_, deoptimization_index_);
}
@@ -79,7 +75,6 @@
LCodeGen* codegen_;
LPointerMap* pointers_;
int deoptimization_index_;
- bool ensure_reloc_space_;
};
@@ -102,6 +97,7 @@
code->set_stack_slots(StackSlotCount());
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
PopulateDeoptimizationData(code);
+ Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
}
@@ -2096,12 +2092,76 @@
}
+void LCodeGen::EmitLoadField(Register result,
+ Register object,
+ Handle<Map> type,
+ Handle<String> name) {
+ LookupResult lookup;
+ type->LookupInDescriptors(NULL, *name, &lookup);
+ ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
+ int index = lookup.GetLocalFieldIndexFromMap(*type);
+ int offset = index * kPointerSize;
+ if (index < 0) {
+ // Negative property indices are in-object properties, indexed
+ // from the end of the fixed part of the object.
+ __ movq(result, FieldOperand(object, offset + type->instance_size()));
+ } else {
+ // Non-negative property indices are in the properties array.
+ __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
+ __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
+ }
+}
+
+
+void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
+ Register object = ToRegister(instr->object());
+ Register result = ToRegister(instr->result());
+
+ int map_count = instr->hydrogen()->types()->length();
+ Handle<String> name = instr->hydrogen()->name();
+
+ if (map_count == 0) {
+ ASSERT(instr->hydrogen()->need_generic());
+ __ Move(rcx, instr->hydrogen()->name());
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ } else {
+ NearLabel done;
+ for (int i = 0; i < map_count - 1; ++i) {
+ Handle<Map> map = instr->hydrogen()->types()->at(i);
+ NearLabel next;
+ __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+ __ j(not_equal, &next);
+ EmitLoadField(result, object, map, name);
+ __ jmp(&done);
+ __ bind(&next);
+ }
+ Handle<Map> map = instr->hydrogen()->types()->last();
+ __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+ if (instr->hydrogen()->need_generic()) {
+ NearLabel generic;
+ __ j(not_equal, &generic);
+ EmitLoadField(result, object, map, name);
+ __ jmp(&done);
+ __ bind(&generic);
+ __ Move(rcx, instr->hydrogen()->name());
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ CallCode(ic, RelocInfo::CODE_TARGET, instr);
+ } else {
+ DeoptimizeIf(not_equal, instr->environment());
+ EmitLoadField(result, object, map, name);
+ }
+ __ bind(&done);
+ }
+}
+
+
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->object()).is(rax));
ASSERT(ToRegister(instr->result()).is(rax));
__ Move(rcx, instr->name());
- Handle<Code> ic(isolate()->builtins()->builtin(Builtins::LoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2157,11 +2217,16 @@
Heap::kFixedArrayMapRootIndex);
__ j(equal, &done);
__ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
- Heap::kExternalPixelArrayMapRootIndex);
- __ j(equal, &done);
- __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
Heap::kFixedCOWArrayMapRootIndex);
- __ Check(equal, "Check for fast elements failed.");
+ __ j(equal, &done);
+ Register temp((result.is(rax)) ? rbx : rax);
+ __ push(temp);
+ __ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
+ __ movzxbq(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
+ __ subq(temp, Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
+ __ cmpq(temp, Immediate(kExternalArrayTypeCount));
+ __ pop(temp);
+ __ Check(below, "Check for fast elements failed.");
__ bind(&done);
}
}
@@ -2212,14 +2277,47 @@
}
-void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
- Register external_elements = ToRegister(instr->external_pointer());
+void LCodeGen::DoLoadKeyedSpecializedArrayElement(
+ LLoadKeyedSpecializedArrayElement* instr) {
+ Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
- Register result = ToRegister(instr->result());
- ASSERT(result.is(external_elements));
-
- // Load the result.
- __ movzxbq(result, Operand(external_elements, key, times_1, 0));
+ ExternalArrayType array_type = instr->array_type();
+ if (array_type == kExternalFloatArray) {
+ XMMRegister result(ToDoubleRegister(instr->result()));
+ __ movss(result, Operand(external_pointer, key, times_4, 0));
+ __ cvtss2sd(result, result);
+ } else {
+ Register result(ToRegister(instr->result()));
+ switch (array_type) {
+ case kExternalByteArray:
+ __ movsxbq(result, Operand(external_pointer, key, times_1, 0));
+ break;
+ case kExternalUnsignedByteArray:
+ case kExternalPixelArray:
+ __ movzxbq(result, Operand(external_pointer, key, times_1, 0));
+ break;
+ case kExternalShortArray:
+ __ movsxwq(result, Operand(external_pointer, key, times_2, 0));
+ break;
+ case kExternalUnsignedShortArray:
+ __ movzxwq(result, Operand(external_pointer, key, times_2, 0));
+ break;
+ case kExternalIntArray:
+ __ movsxlq(result, Operand(external_pointer, key, times_4, 0));
+ break;
+ case kExternalUnsignedIntArray:
+ __ movl(result, Operand(external_pointer, key, times_4, 0));
+ __ testl(result, result);
+ // TODO(danno): we could be more clever here, perhaps having a special
+ // version of the stub that detects if the overflow case actually
+ // happens, and generate code that returns a double rather than int.
+ DeoptimizeIf(negative, instr->environment());
+ break;
+ case kExternalFloatArray:
+ UNREACHABLE();
+ break;
+ }
+ }
}
@@ -2227,8 +2325,7 @@
ASSERT(ToRegister(instr->object()).is(rdx));
ASSERT(ToRegister(instr->key()).is(rax));
- Handle<Code> ic(isolate()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -2343,8 +2440,7 @@
RegisterEnvironmentForDeoptimization(env);
SafepointGenerator safepoint_generator(this,
pointers,
- env->deoptimization_index(),
- true);
+ env->deoptimization_index());
v8::internal::ParameterCount actual(rax);
__ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
}
@@ -2782,8 +2878,7 @@
ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
ASSERT(ToRegister(instr->result()).is(rax));
- Handle<Code> builtin(isolate()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
__ Set(rax, instr->arity());
CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -2829,28 +2924,53 @@
ASSERT(ToRegister(instr->value()).is(rax));
__ Move(rcx, instr->hydrogen()->name());
- Handle<Code> ic(isolate()->builtins()->builtin(
- info_->is_strict() ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ Handle<Code> ic = info_->is_strict()
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
+ : isolate()->builtins()->StoreIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
-void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) {
+void LCodeGen::DoStoreKeyedSpecializedArrayElement(
+ LStoreKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
- Register value = ToRegister(instr->value());
-
- { // Clamp the value to [0..255].
- NearLabel done;
- __ testl(value, Immediate(0xFFFFFF00));
- __ j(zero, &done);
- __ setcc(negative, value); // 1 if negative, 0 if positive.
- __ decb(value); // 0 if negative, 255 if positive.
- __ bind(&done);
+ ExternalArrayType array_type = instr->array_type();
+ if (array_type == kExternalFloatArray) {
+ XMMRegister value(ToDoubleRegister(instr->value()));
+ __ cvtsd2ss(value, value);
+ __ movss(Operand(external_pointer, key, times_4, 0), value);
+ } else {
+ Register value(ToRegister(instr->value()));
+ switch (array_type) {
+ case kExternalPixelArray:
+ { // Clamp the value to [0..255].
+ NearLabel done;
+ __ testl(value, Immediate(0xFFFFFF00));
+ __ j(zero, &done);
+ __ setcc(negative, value); // 1 if negative, 0 if positive.
+ __ decb(value); // 0 if negative, 255 if positive.
+ __ bind(&done);
+ __ movb(Operand(external_pointer, key, times_1, 0), value);
+ }
+ break;
+ case kExternalByteArray:
+ case kExternalUnsignedByteArray:
+ __ movb(Operand(external_pointer, key, times_1, 0), value);
+ break;
+ case kExternalShortArray:
+ case kExternalUnsignedShortArray:
+ __ movw(Operand(external_pointer, key, times_2, 0), value);
+ break;
+ case kExternalIntArray:
+ case kExternalUnsignedIntArray:
+ __ movl(Operand(external_pointer, key, times_4, 0), value);
+ break;
+ case kExternalFloatArray:
+ UNREACHABLE();
+ break;
+ }
}
-
- __ movb(Operand(external_pointer, key, times_1, 0), value);
}
@@ -2900,9 +3020,9 @@
ASSERT(ToRegister(instr->key()).is(rcx));
ASSERT(ToRegister(instr->value()).is(rax));
- Handle<Code> ic(isolate()->builtins()->builtin(
- info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ Handle<Code> ic = info_->is_strict()
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -3791,8 +3911,7 @@
// builtin)
SafepointGenerator safepoint_generator(this,
pointers,
- env->deoptimization_index(),
- true);
+ env->deoptimization_index());
__ Push(Smi::FromInt(strict_mode_flag()));
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
}
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index fcd0a70..f44fdb9 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -241,6 +241,11 @@
// Caller should branch on equal condition.
void EmitIsConstructCall(Register temp);
+ void EmitLoadField(Register result,
+ Register object,
+ Handle<Map> type,
+ Handle<String> name);
+
// Emits code for pushing a constant operand.
void EmitPushConstantOperand(LOperand* operand);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 09b7b63..c47cd72 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1763,6 +1763,21 @@
}
+LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
+ HLoadNamedFieldPolymorphic* instr) {
+ ASSERT(instr->representation().IsTagged());
+ if (instr->need_generic()) {
+ LOperand* obj = UseFixed(instr->object(), rax);
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+ return MarkAsCall(DefineFixed(result, rax), instr);
+ } else {
+ LOperand* obj = UseRegisterAtStart(instr->object());
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+ return AssignEnvironment(DefineAsRegister(result));
+ }
+}
+
+
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* object = UseFixed(instr->object(), rax);
LLoadNamedGeneric* result = new LLoadNamedGeneric(object);
@@ -1801,16 +1816,22 @@
}
-LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
- HLoadPixelArrayElement* instr) {
- ASSERT(instr->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
+ HLoadKeyedSpecializedArrayElement* instr) {
+ ExternalArrayType array_type = instr->array_type();
+ Representation representation(instr->representation());
+ ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+ (representation.IsDouble() && array_type == kExternalFloatArray));
ASSERT(instr->key()->representation().IsInteger32());
- LOperand* external_pointer =
- UseRegisterAtStart(instr->external_pointer());
- LOperand* key = UseRegisterAtStart(instr->key());
- LLoadPixelArrayElement* result =
- new LLoadPixelArrayElement(external_pointer, key);
- return DefineSameAsFirst(result);
+ LOperand* external_pointer = UseRegister(instr->external_pointer());
+ LOperand* key = UseRegister(instr->key());
+ LLoadKeyedSpecializedArrayElement* result =
+ new LLoadKeyedSpecializedArrayElement(external_pointer, key);
+ LInstruction* load_instr = DefineAsRegister(result);
+ // An unsigned int array load might overflow and cause a deopt, make sure it
+ // has an environment.
+ return (array_type == kExternalUnsignedIntArray) ?
+ AssignEnvironment(load_instr) : load_instr;
}
@@ -1842,17 +1863,26 @@
}
-LInstruction* LChunkBuilder::DoStorePixelArrayElement(
- HStorePixelArrayElement* instr) {
- ASSERT(instr->value()->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
+ HStoreKeyedSpecializedArrayElement* instr) {
+ Representation representation(instr->value()->representation());
+ ExternalArrayType array_type = instr->array_type();
+ ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+ (representation.IsDouble() && array_type == kExternalFloatArray));
ASSERT(instr->external_pointer()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer = UseRegister(instr->external_pointer());
- LOperand* val = UseTempRegister(instr->value());
+ bool val_is_temp_register = array_type == kExternalPixelArray ||
+ array_type == kExternalFloatArray;
+ LOperand* val = val_is_temp_register
+ ? UseTempRegister(instr->value())
+ : UseRegister(instr->key());
LOperand* key = UseRegister(instr->key());
- return new LStorePixelArrayElement(external_pointer, key, val);
+ return new LStoreKeyedSpecializedArrayElement(external_pointer,
+ key,
+ val);
}
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index f5c3ddd..e94debf 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -121,10 +121,11 @@
V(LoadGlobal) \
V(LoadKeyedFastElement) \
V(LoadKeyedGeneric) \
+ V(LoadKeyedSpecializedArrayElement) \
V(LoadNamedField) \
+ V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
V(LoadFunctionPrototype) \
- V(LoadPixelArrayElement) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@@ -146,9 +147,9 @@
V(StoreGlobal) \
V(StoreKeyedFastElement) \
V(StoreKeyedGeneric) \
+ V(StoreKeyedSpecializedArrayElement) \
V(StoreNamedField) \
V(StoreNamedGeneric) \
- V(StorePixelArrayElement) \
V(StringCharCodeAt) \
V(StringCharFromCode) \
V(StringLength) \
@@ -1134,6 +1135,19 @@
};
+class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LLoadNamedFieldPolymorphic(LOperand* object) {
+ inputs_[0] = object;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
+ DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
+
+ LOperand* object() { return inputs_[0]; }
+};
+
+
class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
public:
explicit LLoadNamedGeneric(LOperand* object) {
@@ -1197,19 +1211,23 @@
};
-class LLoadPixelArrayElement: public LTemplateInstruction<1, 2, 0> {
+class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
public:
- LLoadPixelArrayElement(LOperand* external_pointer, LOperand* key) {
+ LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
+ LOperand* key) {
inputs_[0] = external_pointer;
inputs_[1] = key;
}
- DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
- "load-pixel-array-element")
- DECLARE_HYDROGEN_ACCESSOR(LoadPixelArrayElement)
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+ "load-keyed-specialized-array-element")
+ DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+ ExternalArrayType array_type() const {
+ return hydrogen()->array_type();
+ }
};
@@ -1587,23 +1605,26 @@
};
-class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
public:
- LStorePixelArrayElement(LOperand* external_pointer,
- LOperand* key,
- LOperand* val) {
+ LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
+ LOperand* key,
+ LOperand* val) {
inputs_[0] = external_pointer;
inputs_[1] = key;
inputs_[2] = val;
}
- DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
- "store-pixel-array-element")
- DECLARE_HYDROGEN_ACCESSOR(StorePixelArrayElement)
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+ "store-keyed-specialized-array-element")
+ DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+ ExternalArrayType array_type() const {
+ return hydrogen()->array_type();
+ }
};
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index b73f5d1..654814c 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -45,13 +45,13 @@
generating_stub_(false),
allow_stub_calls_(true),
root_array_available_(true),
- code_object_(HEAP->undefined_value()) {
+ code_object_(isolate()->heap()->undefined_value()) {
}
-static intptr_t RootRegisterDelta(ExternalReference other) {
+static intptr_t RootRegisterDelta(ExternalReference other, Isolate* isolate) {
Address roots_register_value = kRootRegisterBias +
- reinterpret_cast<Address>(Isolate::Current()->heap()->roots_address());
+ reinterpret_cast<Address>(isolate->heap()->roots_address());
intptr_t delta = other.address() - roots_register_value;
return delta;
}
@@ -60,10 +60,10 @@
Operand MacroAssembler::ExternalOperand(ExternalReference target,
Register scratch) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(target);
+ intptr_t delta = RootRegisterDelta(target, isolate());
if (is_int32(delta)) {
Serializer::TooLateToEnableNow();
- return Operand(kRootRegister, delta);
+ return Operand(kRootRegister, static_cast<int32_t>(delta));
}
}
movq(scratch, target);
@@ -73,7 +73,7 @@
void MacroAssembler::Load(Register destination, ExternalReference source) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(source);
+ intptr_t delta = RootRegisterDelta(source, isolate());
if (is_int32(delta)) {
Serializer::TooLateToEnableNow();
movq(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
@@ -92,7 +92,7 @@
void MacroAssembler::Store(ExternalReference destination, Register source) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(destination);
+ intptr_t delta = RootRegisterDelta(destination, isolate());
if (is_int32(delta)) {
Serializer::TooLateToEnableNow();
movq(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
@@ -112,7 +112,7 @@
void MacroAssembler::LoadAddress(Register destination,
ExternalReference source) {
if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(source);
+ intptr_t delta = RootRegisterDelta(source, isolate());
if (is_int32(delta)) {
Serializer::TooLateToEnableNow();
lea(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
@@ -129,7 +129,7 @@
// This calculation depends on the internals of LoadAddress.
// It's correctness is ensured by the asserts in the Call
// instruction below.
- intptr_t delta = RootRegisterDelta(source);
+ intptr_t delta = RootRegisterDelta(source, isolate());
if (is_int32(delta)) {
Serializer::TooLateToEnableNow();
// Operand is lea(scratch, Operand(kRootRegister, delta));
@@ -909,9 +909,9 @@
Register src,
int constant) {
if (dst.is(src)) {
- addq(dst, Immediate(constant));
+ addl(dst, Immediate(constant));
} else {
- lea(dst, Operand(src, constant));
+ leal(dst, Operand(src, constant));
}
shl(dst, Immediate(kSmiShift));
}
@@ -1245,12 +1245,10 @@
// No overflow checking. Use only when it's known that
// overflowing is impossible.
ASSERT(!dst.is(src2));
- if (dst.is(src1)) {
- addq(dst, src2);
- } else {
+ if (!dst.is(src1)) {
movq(dst, src1);
- addq(dst, src2);
}
+ addq(dst, src2);
Assert(no_overflow, "Smi addition overflow");
}
@@ -1259,12 +1257,10 @@
// No overflow checking. Use only when it's known that
// overflowing is impossible (e.g., subtracting two positive smis).
ASSERT(!dst.is(src2));
- if (dst.is(src1)) {
- subq(dst, src2);
- } else {
+ if (!dst.is(src1)) {
movq(dst, src1);
- subq(dst, src2);
}
+ subq(dst, src2);
Assert(no_overflow, "Smi subtraction overflow");
}
@@ -1274,12 +1270,10 @@
const Operand& src2) {
// No overflow checking. Use only when it's known that
// overflowing is impossible (e.g., subtracting two positive smis).
- if (dst.is(src1)) {
- subq(dst, src2);
- } else {
+ if (!dst.is(src1)) {
movq(dst, src1);
- subq(dst, src2);
}
+ subq(dst, src2);
Assert(no_overflow, "Smi subtraction overflow");
}
@@ -1466,6 +1460,13 @@
}
+void MacroAssembler::AddSmiField(Register dst, const Operand& src) {
+ ASSERT_EQ(0, kSmiShift % kBitsPerByte);
+ addl(dst, Operand(src, kSmiShift / kBitsPerByte));
+}
+
+
+
void MacroAssembler::Move(Register dst, Register src) {
if (!dst.is(src)) {
movq(dst, src);
@@ -2701,6 +2702,70 @@
}
+// Copy memory, byte-by-byte, from source to destination. Not optimized for
+// long or aligned copies. The contents of scratch and length are destroyed.
+// Destination is incremented by length, source, length and scratch are
+// clobbered.
+// A simpler loop is faster on small copies, but slower on large ones.
+// The cld() instruction must have been emitted, to set the direction flag(),
+// before calling this function.
+void MacroAssembler::CopyBytes(Register destination,
+ Register source,
+ Register length,
+ int min_length,
+ Register scratch) {
+ ASSERT(min_length >= 0);
+ if (FLAG_debug_code) {
+ cmpl(length, Immediate(min_length));
+ Assert(greater_equal, "Invalid min_length");
+ }
+ Label loop, done, short_string, short_loop;
+
+ const int kLongStringLimit = 20;
+ if (min_length <= kLongStringLimit) {
+ cmpl(length, Immediate(kLongStringLimit));
+ j(less_equal, &short_string);
+ }
+
+ ASSERT(source.is(rsi));
+ ASSERT(destination.is(rdi));
+ ASSERT(length.is(rcx));
+
+ // Because source is 8-byte aligned in our uses of this function,
+ // we keep source aligned for the rep movs operation by copying the odd bytes
+ // at the end of the ranges.
+ movq(scratch, length);
+ shrl(length, Immediate(3));
+ repmovsq();
+ // Move remaining bytes of length.
+ andl(scratch, Immediate(0x7));
+ movq(length, Operand(source, scratch, times_1, -8));
+ movq(Operand(destination, scratch, times_1, -8), length);
+ addq(destination, scratch);
+
+ if (min_length <= kLongStringLimit) {
+ jmp(&done);
+
+ bind(&short_string);
+ if (min_length == 0) {
+ testl(length, length);
+ j(zero, &done);
+ }
+ lea(scratch, Operand(destination, length, times_1, 0));
+
+ bind(&short_loop);
+ movb(length, Operand(source, 0));
+ movb(Operand(destination, 0), length);
+ incq(source);
+ incq(destination);
+ cmpq(destination, scratch);
+ j(not_equal, &short_loop);
+
+ bind(&done);
+ }
+}
+
+
void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
if (context_chain_length > 0) {
// Move up the chain of contexts to the context containing the slot.
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index eb1f42d..1ee0fe0 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -470,6 +470,11 @@
Register src1,
Register src2,
LabelType* on_not_smi_result);
+ template <typename LabelType>
+ void SmiAdd(Register dst,
+ Register src1,
+ const Operand& src2,
+ LabelType* on_not_smi_result);
void SmiAdd(Register dst,
Register src1,
@@ -590,6 +595,10 @@
// Converts a positive smi to a negative index.
SmiIndex SmiToNegativeIndex(Register dst, Register src, int shift);
+ // Add the value of a smi in memory to an int32 register.
+ // Sets flags as a normal add.
+ void AddSmiField(Register dst, const Operand& src);
+
// Basic Smi operations.
void Move(Register dst, Smi* source) {
LoadSmiConstant(dst, source);
@@ -1022,6 +1031,18 @@
Handle<Object> CodeObject() { return code_object_; }
+ // Copy length bytes from source to destination.
+ // Uses scratch register internally (if you have a low-eight register
+ // free, do use it, otherwise kScratchRegister will be used).
+ // The min_length is a minimum limit on the value that length will have.
+ // The algorithm has some special cases that might be omitted if the string
+ // is known to always be long.
+ void CopyBytes(Register destination,
+ Register source,
+ Register length,
+ int min_length = 0,
+ Register scratch = kScratchRegister);
+
// ---------------------------------------------------------------------------
// StatsCounter support
@@ -1273,6 +1294,26 @@
template <typename LabelType>
+void MacroAssembler::SmiAdd(Register dst,
+ Register src1,
+ const Operand& src2,
+ LabelType* on_not_smi_result) {
+ ASSERT_NOT_NULL(on_not_smi_result);
+ if (dst.is(src1)) {
+ movq(kScratchRegister, src1);
+ addq(kScratchRegister, src2);
+ j(overflow, on_not_smi_result);
+ movq(dst, kScratchRegister);
+ } else {
+ ASSERT(!src2.AddressUsesRegister(dst));
+ movq(dst, src1);
+ addq(dst, src2);
+ j(overflow, on_not_smi_result);
+ }
+}
+
+
+template <typename LabelType>
void MacroAssembler::SmiSub(Register dst,
Register src1,
Register src2,
@@ -1910,9 +1951,7 @@
}
if (!definitely_matches) {
- Handle<Code> adaptor =
- Handle<Code>(Isolate::Current()->builtins()->builtin(
- Builtins::ArgumentsAdaptorTrampoline));
+ Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
if (!code_constant.is_null()) {
movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index ac2a305..403a1dc 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -89,8 +89,9 @@
Register r0,
Register r1) {
ASSERT(name->IsSymbol());
- __ IncrementCounter(COUNTERS->negative_lookups(), 1);
- __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->negative_lookups(), 1);
+ __ IncrementCounter(counters->negative_lookups_miss(), 1);
Label done;
__ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset));
@@ -173,7 +174,7 @@
}
__ bind(&done);
- __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1);
+ __ DecrementCounter(counters->negative_lookups_miss(), 1);
}
@@ -184,7 +185,7 @@
Register scratch,
Register extra,
Register extra2) {
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = masm->isolate();
Label miss;
USE(extra); // The register extra is not used on the X64 platform.
USE(extra2); // The register extra2 is not used on the X64 platform.
@@ -255,14 +256,15 @@
void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
MacroAssembler* masm, int index, Register prototype, Label* miss) {
+ Isolate* isolate = masm->isolate();
// Check we're still in the same context.
- __ Move(prototype, Isolate::Current()->global());
+ __ Move(prototype, isolate->global());
__ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)),
prototype);
__ j(not_equal, miss);
// Get the global function with the given index.
- JSFunction* function = JSFunction::cast(
- Isolate::Current()->global_context()->get(index));
+ JSFunction* function =
+ JSFunction::cast(isolate->global_context()->get(index));
// Load its initial map. The global functions all have initial maps.
__ Move(prototype, Handle<Map>(function->initial_map()));
// Load the prototype from the initial map.
@@ -601,10 +603,11 @@
(depth2 != kInvalidProtoDepth);
}
- __ IncrementCounter(COUNTERS->call_const_interceptor(), 1);
+ Counters* counters = masm->isolate()->counters();
+ __ IncrementCounter(counters->call_const_interceptor(), 1);
if (can_do_fast_api_call) {
- __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1);
+ __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1);
ReserveSpaceForFastApiCall(masm, scratch1);
}
@@ -734,9 +737,9 @@
ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
Code* code = NULL;
if (kind == Code::LOAD_IC) {
- code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss);
+ code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
} else {
- code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
+ code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
}
Handle<Code> ic(code);
@@ -1322,7 +1325,7 @@
MaybeObject* CallStubCompiler::GenerateMissBranch() {
- MaybeObject* maybe_obj = Isolate::Current()->stub_cache()->ComputeCallMiss(
+ MaybeObject* maybe_obj = masm()->isolate()->stub_cache()->ComputeCallMiss(
arguments().immediate(), kind_);
Object* obj;
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
@@ -2006,8 +2009,9 @@
// Check that the receiver isn't a smi.
__ JumpIfSmi(rdx, &miss_before_stack_reserved);
- __ IncrementCounter(COUNTERS->call_const(), 1);
- __ IncrementCounter(COUNTERS->call_const_fast_api(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->call_const(), 1);
+ __ IncrementCounter(counters->call_const_fast_api(), 1);
// Allocate space for v8::Arguments implicit values. Must be initialized
// before calling any runtime function.
@@ -2077,10 +2081,11 @@
// unless we're doing a receiver map check.
ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
+ Counters* counters = masm()->isolate()->counters();
SharedFunctionInfo* function_info = function->shared();
switch (check) {
case RECEIVER_MAP_CHECK:
- __ IncrementCounter(COUNTERS->call_const(), 1);
+ __ IncrementCounter(counters->call_const(), 1);
// Check that the maps haven't changed.
CheckPrototypes(JSObject::cast(object), rdx, holder,
@@ -2282,7 +2287,8 @@
__ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
- __ IncrementCounter(COUNTERS->call_global_inline(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->call_global_inline(), 1);
ASSERT(function->is_compiled());
ParameterCount expected(function->shared()->formal_parameter_count());
if (V8::UseCrankshaft()) {
@@ -2298,7 +2304,7 @@
}
// Handle call cache miss.
__ bind(&miss);
- __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1);
+ __ IncrementCounter(counters->call_global_inline_miss(), 1);
MaybeObject* maybe_result = GenerateMissBranch();
if (maybe_result->IsFailure()) return maybe_result;
@@ -2329,8 +2335,7 @@
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2381,8 +2386,7 @@
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2432,8 +2436,7 @@
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2470,14 +2473,14 @@
__ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rax);
// Return the value (register rax).
- __ IncrementCounter(COUNTERS->named_store_global_inline(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->named_store_global_inline(), 1);
__ ret(0);
// Handle store cache miss.
__ bind(&miss);
- __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_Miss));
+ __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
+ Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2497,7 +2500,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_store_field(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_store_field(), 1);
// Check that the name has not changed.
__ Cmp(rcx, Handle<String>(name));
@@ -2513,9 +2517,8 @@
// Handle store cache miss.
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_store_field(), 1);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_Miss));
+ __ DecrementCounter(counters->keyed_store_field(), 1);
+ Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
__ Jump(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2572,8 +2575,7 @@
// Handle store cache miss.
__ bind(&miss);
- Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_Miss));
+ Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
__ jmp(ic, RelocInfo::CODE_TARGET);
// Return the generated code.
@@ -2761,12 +2763,13 @@
__ Check(not_equal, "DontDelete cells can't contain the hole");
}
- __ IncrementCounter(COUNTERS->named_load_global_stub(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->named_load_global_stub(), 1);
__ movq(rax, rbx);
__ ret(0);
__ bind(&miss);
- __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1);
+ __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
@@ -2785,7 +2788,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_field(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_field(), 1);
// Check that the name has not changed.
__ Cmp(rax, Handle<String>(name));
@@ -2794,7 +2798,7 @@
GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_field(), 1);
+ __ DecrementCounter(counters->keyed_load_field(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -2814,7 +2818,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_callback(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_callback(), 1);
// Check that the name has not changed.
__ Cmp(rax, Handle<String>(name));
@@ -2829,7 +2834,7 @@
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_callback(), 1);
+ __ DecrementCounter(counters->keyed_load_callback(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -2848,7 +2853,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_constant_function(), 1);
// Check that the name has not changed.
__ Cmp(rax, Handle<String>(name));
@@ -2857,7 +2863,7 @@
GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi,
value, name, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+ __ DecrementCounter(counters->keyed_load_constant_function(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -2875,7 +2881,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_interceptor(), 1);
// Check that the name has not changed.
__ Cmp(rax, Handle<String>(name));
@@ -2894,7 +2901,7 @@
name,
&miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+ __ DecrementCounter(counters->keyed_load_interceptor(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -2910,7 +2917,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_array_length(), 1);
// Check that the name has not changed.
__ Cmp(rax, Handle<String>(name));
@@ -2918,7 +2926,7 @@
GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1);
+ __ DecrementCounter(counters->keyed_load_array_length(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -2934,7 +2942,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_string_length(), 1);
// Check that the name has not changed.
__ Cmp(rax, Handle<String>(name));
@@ -2942,7 +2951,7 @@
GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1);
+ __ DecrementCounter(counters->keyed_load_string_length(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -2958,7 +2967,8 @@
// -----------------------------------
Label miss;
- __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
// Check that the name has not changed.
__ Cmp(rax, Handle<String>(name));
@@ -2966,7 +2976,7 @@
GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss);
__ bind(&miss);
- __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+ __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
@@ -3135,15 +3145,16 @@
__ pop(rcx);
__ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize));
__ push(rcx);
- __ IncrementCounter(COUNTERS->constructed_objects(), 1);
- __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->constructed_objects(), 1);
+ __ IncrementCounter(counters->constructed_objects_stub(), 1);
__ ret(0);
// Jump to the generic stub in case the specialized code cannot handle the
// construction.
__ bind(&generic_stub_call);
- Code* code = Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructStubGeneric);
+ Code* code =
+ masm()->isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric);
Handle<Code> generic_construct_stub(code);
__ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
@@ -3258,7 +3269,8 @@
// Slow case: Jump to runtime.
__ bind(&slow);
- __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1);
+ Counters* counters = masm()->isolate()->counters();
+ __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
// ----------- S t a t e -------------
// -- rax : key
diff --git a/src/x64/virtual-frame-x64.cc b/src/x64/virtual-frame-x64.cc
index 6bd7965..10c327a 100644
--- a/src/x64/virtual-frame-x64.cc
+++ b/src/x64/virtual-frame-x64.cc
@@ -1116,7 +1116,7 @@
// Name and receiver are on the top of the frame. Both are dropped.
// The IC expects name in rcx and receiver in rax.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Builtins::kLoadIC_Initialize));
Result name = Pop();
Result receiver = Pop();
PrepareForCall(0, 0);
@@ -1134,7 +1134,7 @@
MoveResultsToRegisters(&key, &receiver, rax, rdx);
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_Initialize));
+ Builtins::kKeyedLoadIC_Initialize));
return RawCallCodeObject(ic, mode);
}
@@ -1145,8 +1145,8 @@
// Value and (if not contextual) receiver are on top of the frame.
// The IC expects name in rcx, value in rax, and receiver in rdx.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
- : Builtins::StoreIC_Initialize));
+ (strict_mode == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+ : Builtins::kStoreIC_Initialize));
Result value = Pop();
RelocInfo::Mode mode;
if (is_contextual) {
@@ -1211,8 +1211,8 @@
}
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- (strict_mode == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
- : Builtins::KeyedStoreIC_Initialize));
+ (strict_mode == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+ : Builtins::kKeyedStoreIC_Initialize));
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
}
@@ -1260,7 +1260,7 @@
// IC expects arg count in rax, function in rdi, and the arguments
// and receiver on the stack.
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::JSConstructCall));
+ Builtins::kJSConstructCall));
// Duplicate the function before preparing the frame.
PushElementAt(arg_count);
Result function = Pop();
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index 7038137..596166c 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -41,8 +41,8 @@
'test-alloc.cc',
'test-api.cc',
'test-ast.cc',
- 'test-bignum.cc',
'test-bignum-dtoa.cc',
+ 'test-bignum.cc',
'test-circular-queue.cc',
'test-compiler.cc',
'test-conversions.cc',
@@ -59,15 +59,16 @@
'test-flags.cc',
'test-func-name-inference.cc',
'test-hashmap.cc',
- 'test-heap.cc',
'test-heap-profiler.cc',
+ 'test-heap.cc',
'test-list.cc',
'test-liveedit.cc',
'test-lock.cc',
- 'test-log.cc',
'test-log-utils.cc',
+ 'test-log.cc',
'test-mark-compact.cc',
'test-parsing.cc',
+ 'test-platform-tls.cc',
'test-profile-generator.cc',
'test-regexp.cc',
'test-reloc-info.cc',
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index 00ff866..3d8157d 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -91,7 +91,7 @@
// Test that we can allocate in old pointer space and code space.
CHECK(!heap->AllocateFixedArray(100, TENURED)->IsFailure());
CHECK(!heap->CopyCode(Isolate::Current()->builtins()->builtin(
- Builtins::Illegal))->IsFailure());
+ Builtins::kIllegal))->IsFailure());
// Return success.
return Smi::FromInt(42);
@@ -135,7 +135,7 @@
// something empty.
FACTORY->NewJSObject(function);
function->ReplaceCode(Isolate::Current()->builtins()->builtin(
- Builtins::EmptyFunction));
+ Builtins::kEmptyFunction));
// Patch the map to have an accessor for "get".
Handle<Map> map(function->initial_map());
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 42b6ad2..33d505e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -3870,10 +3870,8 @@
source = v8_str("undetectable.y = 2000;");
script = Script::Compile(source);
- v8::TryCatch try_catch;
Local<Value> result = script->Run();
- CHECK(result.IsEmpty());
- CHECK(try_catch.HasCaught());
+ ExpectBoolean("undetectable.y == undefined", true);
}
@@ -4744,130 +4742,130 @@
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen);
- CHECK_EQ(len, 9);
- CHECK_EQ(charlen, 5);
- CHECK_EQ(strcmp(utf8buf, "abc\303\260\342\230\203"), 0);
+ CHECK_EQ(9, len);
+ CHECK_EQ(5, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203"));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 8, &charlen);
- CHECK_EQ(len, 8);
- CHECK_EQ(charlen, 5);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\342\230\203\1", 9), 0);
+ CHECK_EQ(8, len);
+ CHECK_EQ(5, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\342\230\203\1", 9));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 7, &charlen);
- CHECK_EQ(len, 5);
- CHECK_EQ(charlen, 4);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(4, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 6, &charlen);
- CHECK_EQ(len, 5);
- CHECK_EQ(charlen, 4);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(4, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 5, &charlen);
- CHECK_EQ(len, 5);
- CHECK_EQ(charlen, 4);
- CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(4, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 4, &charlen);
- CHECK_EQ(len, 3);
- CHECK_EQ(charlen, 3);
- CHECK_EQ(strncmp(utf8buf, "abc\1", 4), 0);
+ CHECK_EQ(3, len);
+ CHECK_EQ(3, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 3, &charlen);
- CHECK_EQ(len, 3);
- CHECK_EQ(charlen, 3);
- CHECK_EQ(strncmp(utf8buf, "abc\1", 4), 0);
+ CHECK_EQ(3, len);
+ CHECK_EQ(3, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
memset(utf8buf, 0x1, sizeof(utf8buf));
len = str2->WriteUtf8(utf8buf, 2, &charlen);
- CHECK_EQ(len, 2);
- CHECK_EQ(charlen, 2);
- CHECK_EQ(strncmp(utf8buf, "ab\1", 3), 0);
+ CHECK_EQ(2, len);
+ CHECK_EQ(2, charlen);
+ CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf);
- CHECK_EQ(len, 5);
+ CHECK_EQ(5, len);
len = str->Write(wbuf);
- CHECK_EQ(len, 5);
- CHECK_EQ(strcmp("abcde", buf), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(0, strcmp("abcde", buf));
uint16_t answer1[] = {'a', 'b', 'c', 'd', 'e', '\0'};
- CHECK_EQ(StrCmp16(answer1, wbuf), 0);
+ CHECK_EQ(0, StrCmp16(answer1, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 4);
- CHECK_EQ(len, 4);
+ CHECK_EQ(4, len);
len = str->Write(wbuf, 0, 4);
- CHECK_EQ(len, 4);
- CHECK_EQ(strncmp("abcd\1", buf, 5), 0);
+ CHECK_EQ(4, len);
+ CHECK_EQ(0, strncmp("abcd\1", buf, 5));
uint16_t answer2[] = {'a', 'b', 'c', 'd', 0x101};
- CHECK_EQ(StrNCmp16(answer2, wbuf, 5), 0);
+ CHECK_EQ(0, StrNCmp16(answer2, wbuf, 5));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 5);
- CHECK_EQ(len, 5);
+ CHECK_EQ(5, len);
len = str->Write(wbuf, 0, 5);
- CHECK_EQ(len, 5);
- CHECK_EQ(strncmp("abcde\1", buf, 6), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(0, strncmp("abcde\1", buf, 6));
uint16_t answer3[] = {'a', 'b', 'c', 'd', 'e', 0x101};
- CHECK_EQ(StrNCmp16(answer3, wbuf, 6), 0);
+ CHECK_EQ(0, StrNCmp16(answer3, wbuf, 6));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 6);
- CHECK_EQ(len, 5);
+ CHECK_EQ(5, len);
len = str->Write(wbuf, 0, 6);
- CHECK_EQ(len, 5);
- CHECK_EQ(strcmp("abcde", buf), 0);
+ CHECK_EQ(5, len);
+ CHECK_EQ(0, strcmp("abcde", buf));
uint16_t answer4[] = {'a', 'b', 'c', 'd', 'e', '\0'};
- CHECK_EQ(StrCmp16(answer4, wbuf), 0);
+ CHECK_EQ(0, StrCmp16(answer4, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, -1);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 4, -1);
- CHECK_EQ(len, 1);
- CHECK_EQ(strcmp("e", buf), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strcmp("e", buf));
uint16_t answer5[] = {'e', '\0'};
- CHECK_EQ(StrCmp16(answer5, wbuf), 0);
+ CHECK_EQ(0, StrCmp16(answer5, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, 6);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 4, 6);
- CHECK_EQ(len, 1);
- CHECK_EQ(strcmp("e", buf), 0);
- CHECK_EQ(StrCmp16(answer5, wbuf), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strcmp("e", buf));
+ CHECK_EQ(0, StrCmp16(answer5, wbuf));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, 1);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 4, 1);
- CHECK_EQ(len, 1);
- CHECK_EQ(strncmp("e\1", buf, 2), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strncmp("e\1", buf, 2));
uint16_t answer6[] = {'e', 0x101};
- CHECK_EQ(StrNCmp16(answer6, wbuf, 2), 0);
+ CHECK_EQ(0, StrNCmp16(answer6, wbuf, 2));
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 3, 1);
- CHECK_EQ(len, 1);
+ CHECK_EQ(1, len);
len = str->Write(wbuf, 3, 1);
- CHECK_EQ(len, 1);
- CHECK_EQ(strncmp("d\1", buf, 2), 0);
+ CHECK_EQ(1, len);
+ CHECK_EQ(0, strncmp("d\1", buf, 2));
uint16_t answer7[] = {'d', 0x101};
- CHECK_EQ(StrNCmp16(answer7, wbuf, 2), 0);
+ CHECK_EQ(0, StrNCmp16(answer7, wbuf, 2));
}
@@ -11492,6 +11490,35 @@
CHECK_EQ(true, result->BooleanValue());
}
+ // Test crankshaft external array loads
+ for (int i = 0; i < kElementCount; i++) {
+ array->set(i, static_cast<ElementType>(i));
+ }
+ result = CompileRun("function ee_load_test_func(sum) {"
+ " for (var i=0;i<40;++i)"
+ " sum += ext_array[i];"
+ " return sum;"
+ "}"
+ "sum=0;"
+ "for (var i=0;i<10000;++i) {"
+ " sum=ee_load_test_func(sum);"
+ "}"
+ "sum;");
+ CHECK_EQ(7800000, result->Int32Value());
+
+ // Test crankshaft external array stores
+ result = CompileRun("function ee_store_test_func(sum) {"
+ " for (var i=0;i<40;++i)"
+ " sum += ext_array[i] = i;"
+ " return sum;"
+ "}"
+ "sum=0;"
+ "for (var i=0;i<10000;++i) {"
+ " sum=ee_store_test_func(sum);"
+ "}"
+ "sum;");
+ CHECK_EQ(7800000, result->Int32Value());
+
result = CompileRun("ext_array[3] = 33;"
"delete ext_array[3];"
"ext_array[3];");
@@ -11598,6 +11625,95 @@
free(large_array_data);
}
+ // The "" property descriptor is overloaded to store information about
+ // the external array. Ensure that setting and accessing the "" property
+ // works (it should overwrite the information cached about the external
+ // array in the DescriptorArray) in various situations.
+ result = CompileRun("ext_array[''] = 23; ext_array['']");
+ CHECK_EQ(23, result->Int32Value());
+
+ // Property "" set after the external array is associated with the object.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field"), v8::Int32::New(256));
+ obj2->Set(v8_str(""), v8::Int32::New(1503));
+ // Set the elements to be the external array.
+ obj2->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array['']");
+ CHECK_EQ(1503, result->Int32Value());
+ }
+
+ // Property "" set after the external array is associated with the object.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256));
+ // Set the elements to be the external array.
+ obj2->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ obj2->Set(v8_str(""), v8::Int32::New(1503));
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array['']");
+ CHECK_EQ(1503, result->Int32Value());
+ }
+
+ // Should reuse the map from previous test.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256));
+ // Set the elements to be the external array. Should re-use the map
+ // from previous test.
+ obj2->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array['']");
+ }
+
+ // Property "" is a constant function that shouldn't not be interfered with
+ // when an external array is set.
+ {
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ // Start
+ obj2->Set(v8_str("ee_test_field3"), v8::Int32::New(256));
+
+ // Add a constant function to an object.
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array[''] = function() {return 1503;};"
+ "ext_array['']();");
+
+ // Add an external array transition to the same map that
+ // has the constant transition.
+ v8::Handle<v8::Object> obj3 = v8::Object::New();
+ obj3->Set(v8_str("ee_test_field3"), v8::Int32::New(256));
+ obj3->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+ context->Global()->Set(v8_str("ext_array"), obj3);
+ }
+
+ // If a external array transition is in the map, it should get clobbered
+ // by a constant function.
+ {
+ // Add an external array transition.
+ v8::Handle<v8::Object> obj3 = v8::Object::New();
+ obj3->Set(v8_str("ee_test_field4"), v8::Int32::New(256));
+ obj3->SetIndexedPropertiesToExternalArrayData(array_data,
+ array_type,
+ kElementCount);
+
+ // Add a constant function to the same map that just got an external array
+ // transition.
+ v8::Handle<v8::Object> obj2 = v8::Object::New();
+ obj2->Set(v8_str("ee_test_field4"), v8::Int32::New(256));
+ context->Global()->Set(v8_str("ext_array"), obj2);
+ result = CompileRun("ext_array[''] = function() {return 1503;};"
+ "ext_array['']();");
+ }
+
free(array_data);
}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 9622968..b81129e 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -1022,13 +1022,13 @@
0,
v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
Isolate::Current()->builtins()->builtin(
- Builtins::StoreIC_DebugBreak));
+ Builtins::kStoreIC_DebugBreak));
CheckDebugBreakFunction(&env,
"function f3(){var a=x;}", "f3",
0,
v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_DebugBreak));
+ Builtins::kLoadIC_DebugBreak));
// TODO(1240753): Make the test architecture independent or split
// parts of the debugger into architecture dependent files. This
@@ -1042,7 +1042,7 @@
0,
v8::internal::RelocInfo::CODE_TARGET,
Isolate::Current()->builtins()->builtin(
- Builtins::KeyedStoreIC_DebugBreak));
+ Builtins::kKeyedStoreIC_DebugBreak));
CheckDebugBreakFunction(
&env,
"function f5(){var index='propertyName'; var a={}; return a[index];}",
@@ -1050,7 +1050,7 @@
0,
v8::internal::RelocInfo::CODE_TARGET,
Isolate::Current()->builtins()->builtin(
- Builtins::KeyedLoadIC_DebugBreak));
+ Builtins::kKeyedLoadIC_DebugBreak));
#endif
// Check the debug break code stubs for call ICs with different number of
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index d65656a..26da5c9 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -273,7 +273,7 @@
__ call(Operand(ebx, ecx, times_4, 10000));
__ nop();
Handle<Code> ic(Isolate::Current()->builtins()->builtin(
- Builtins::LoadIC_Initialize));
+ Builtins::kLoadIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
__ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
diff --git a/test/cctest/test-macro-assembler-x64.cc b/test/cctest/test-macro-assembler-x64.cc
index 15dc6db..c7c67b0 100755
--- a/test/cctest/test-macro-assembler-x64.cc
+++ b/test/cctest/test-macro-assembler-x64.cc
@@ -95,6 +95,7 @@
static void EntryCode(MacroAssembler* masm) {
// Smi constant register is callee save.
__ push(v8::internal::kSmiConstantRegister);
+ __ push(v8::internal::kRootRegister);
__ InitializeSmiConstantRegister();
__ InitializeRootRegister();
}
@@ -106,6 +107,7 @@
__ cmpq(rdx, v8::internal::kSmiConstantRegister);
__ movq(rdx, Immediate(-1));
__ cmovq(not_equal, rax, rdx);
+ __ pop(v8::internal::kRootRegister);
__ pop(v8::internal::kSmiConstantRegister);
}
diff --git a/test/cctest/test-platform-tls.cc b/test/cctest/test-platform-tls.cc
new file mode 100644
index 0000000..b2cb101
--- /dev/null
+++ b/test/cctest/test-platform-tls.cc
@@ -0,0 +1,66 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+//
+// Tests of fast TLS support.
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "checks.h"
+#include "platform.h"
+
+using v8::internal::Thread;
+
+static const int kValueCount = 128;
+
+static Thread::LocalStorageKey keys[kValueCount];
+
+static void* GetValue(int num) {
+ return reinterpret_cast<void*>(static_cast<intptr_t>(num + 1));
+}
+
+static void DoTest() {
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK(!Thread::HasThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ Thread::SetThreadLocal(keys[i], GetValue(i));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK(Thread::HasThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys[i]));
+ CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ Thread::SetThreadLocal(keys[i], GetValue(kValueCount - i - 1));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK(Thread::HasThreadLocal(keys[i]));
+ }
+ for (int i = 0; i < kValueCount; i++) {
+ CHECK_EQ(GetValue(kValueCount - i - 1),
+ Thread::GetThreadLocal(keys[i]));
+ CHECK_EQ(GetValue(kValueCount - i - 1),
+ Thread::GetExistingThreadLocal(keys[i]));
+ }
+}
+
+class TestThread : public Thread {
+ public:
+ TestThread() : Thread(NULL, "TestThread") {}
+
+ virtual void Run() {
+ DoTest();
+ }
+};
+
+TEST(FastTLS) {
+ for (int i = 0; i < kValueCount; i++) {
+ keys[i] = Thread::CreateThreadLocalKey();
+ }
+ DoTest();
+ TestThread thread;
+ thread.Start();
+ thread.Join();
+}
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index ff01985..730d72a 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -104,14 +104,14 @@
isolate->stats_table()->SetCounterFunction(counter_function);
HEAP->Setup(false);
ExternalReferenceEncoder encoder;
- CHECK_EQ(make_code(BUILTIN, Builtins::ArrayCode),
- Encode(encoder, Builtins::ArrayCode));
+ CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode),
+ Encode(encoder, Builtins::kArrayCode));
CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort),
Encode(encoder, Runtime::kAbort));
CHECK_EQ(make_code(IC_UTILITY, IC::kLoadCallbackProperty),
Encode(encoder, IC_Utility(IC::kLoadCallbackProperty)));
ExternalReference keyed_load_function_prototype =
- ExternalReference(COUNTERS->keyed_load_function_prototype());
+ ExternalReference(isolate->counters()->keyed_load_function_prototype());
CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype),
encoder.Encode(keyed_load_function_prototype.address()));
ExternalReference the_hole_value_location =
@@ -144,15 +144,15 @@
isolate->stats_table()->SetCounterFunction(counter_function);
HEAP->Setup(false);
ExternalReferenceDecoder decoder;
- CHECK_EQ(AddressOf(Builtins::ArrayCode),
- decoder.Decode(make_code(BUILTIN, Builtins::ArrayCode)));
+ CHECK_EQ(AddressOf(Builtins::kArrayCode),
+ decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode)));
CHECK_EQ(AddressOf(Runtime::kAbort),
decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION,
Runtime::kAbort)));
CHECK_EQ(AddressOf(IC_Utility(IC::kLoadCallbackProperty)),
decoder.Decode(make_code(IC_UTILITY, IC::kLoadCallbackProperty)));
ExternalReference keyed_load_function =
- ExternalReference(COUNTERS->keyed_load_function_prototype());
+ ExternalReference(isolate->counters()->keyed_load_function_prototype());
CHECK_EQ(keyed_load_function.address(),
decoder.Decode(
make_code(STATS_COUNTER,
diff --git a/test/mjsunit/compiler/array-length.js b/test/mjsunit/compiler/array-length.js
index 7adb9ab..126c7a0 100644
--- a/test/mjsunit/compiler/array-length.js
+++ b/test/mjsunit/compiler/array-length.js
@@ -36,7 +36,7 @@
var a0 = [];
var a2 = [1,2];
var a5 = [1,2,3,4,5];
-for (var i = 0; i < 10000000; i++) Test(a0, a2, a5);
+for (var i = 0; i < 100000; i++) Test(a0, a2, a5);
assertEquals("undefined", typeof(ArrayLength(0)));
-for (var i = 0; i < 10000000; i++) Test(a0, a2, a5);
+for (var i = 0; i < 100000; i++) Test(a0, a2, a5);
assertEquals(4, ArrayLength("hest"));
diff --git a/test/mjsunit/compiler/global-accessors.js b/test/mjsunit/compiler/global-accessors.js
deleted file mode 100644
index e69de29..0000000
--- a/test/mjsunit/compiler/global-accessors.js
+++ /dev/null
diff --git a/test/mjsunit/compiler/regress-loadfield.js b/test/mjsunit/compiler/regress-loadfield.js
new file mode 100644
index 0000000..a202891
--- /dev/null
+++ b/test/mjsunit/compiler/regress-loadfield.js
@@ -0,0 +1,65 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Regression test for GVN on field loads.
+
+function bar() {}
+
+// Make sure there is a transition on adding "bar" inobject property.
+var b = new bar();
+b.bar = "bar";
+
+function test(a) {
+ var b = new Array(10);
+ for (var i = 0; i < 10; i++) {
+ b[i] = new bar();
+ }
+
+ for (var i = 0; i < 10; i++) {
+ b[i].bar = a.foo;
+ }
+}
+
+// Create an object with fast backing store properties.
+var a = {};
+a.p1 = "";
+a.p2 = "";
+a.p3 = "";
+a.p4 = "";
+a.p5 = "";
+a.p6 = "";
+a.p7 = "";
+a.p8 = "";
+a.p9 = "";
+a.p10 = "";
+a.p11 = "";
+a.foo = "foo";
+for (var i = 0; i < 100000; i++) {
+ test(a);
+}
+
+test("");
diff --git a/test/mjsunit/math-sqrt.js b/test/mjsunit/math-sqrt.js
index fb00d5b..43fbf6b 100644
--- a/test/mjsunit/math-sqrt.js
+++ b/test/mjsunit/math-sqrt.js
@@ -29,7 +29,11 @@
function test(expected_sqrt, value) {
assertEquals(expected_sqrt, Math.sqrt(value));
- if (isFinite(value)) {
+ if (isFinite(value)) {
+ if (value === 0 && (1 / value) == -Infinity) {
+ // Math.pow(-0, 0.5) must be zero, but Math.sqrt(-0) is -0.
+ expected_sqrt = 0;
+ }
assertEquals(expected_sqrt, Math.pow(value, 0.5));
}
}
diff --git a/test/mjsunit/mjsunit.js b/test/mjsunit/mjsunit.js
index fe580f3..436bdc8 100644
--- a/test/mjsunit/mjsunit.js
+++ b/test/mjsunit/mjsunit.js
@@ -41,15 +41,62 @@
* the f-word and ignore all other lines.
*/
+function MjsUnitToString(value) {
+ switch (typeof value) {
+ case "string":
+ return JSON.stringify(value);
+ case "number":
+ if (value === 0 && (1 / value) < 0) return "-0";
+ case "boolean":
+ case "null":
+ case "undefined":
+ case "function":
+ return String(value);
+ case "object":
+ if (value === null) return "null";
+ var clazz = Object.prototype.toString.call(value);
+ clazz = clazz.substring(8, clazz.length - 1);
+ switch (clazz) {
+ case "Number":
+ case "String":
+ case "Boolean":
+ case "Date":
+ return clazz + "(" + MjsUnitToString(value.valueOf()) + ")";
+ case "RegExp":
+ return value.toString();
+ case "Array":
+ return "[" + value.map(MjsUnitArrayElementToString).join(",") + "]";
+ case "Object":
+ break;
+ default:
+ return clazz + "()";
+ }
+ // [[Class]] is "Object".
+ var constructor = value.constructor.name;
+ if (name) return name + "()";
+ return "Object()";
+ default:
+ return "-- unknown value --";
+ }
+}
+
+
+function MjsUnitArrayElementToString(value, index, array) {
+ if (value === undefined && !(index in array)) return "";
+ return MjsUnitToString(value);
+}
+
+
function fail(expected, found, name_opt) {
- var start;
+ var message = "Fail" + "ure";
if (name_opt) {
// Fix this when we ditch the old test runner.
- start = "Fail" + "ure (" + name_opt + "): ";
- } else {
- start = "Fail" + "ure:";
+ message += " (" + name_opt + ")";
}
- throw new MjsUnitAssertionError(start + " expected <" + expected + "> found <" + found + ">");
+
+ message += ": expected <" + MjsUnitToString(expected) +
+ "> found <" + MjsUnitToString(found) + ">";
+ throw new MjsUnitAssertionError(message);
}
@@ -73,13 +120,17 @@
function deepEquals(a, b) {
- if (a == b) return true;
+ if (a == b) {
+ // Check for -0.
+ if (a === 0 && b === 0) return (1 / a) === (1 / b);
+ return true;
+ }
if (typeof a == "number" && typeof b == "number" && isNaN(a) && isNaN(b)) {
return true;
}
if (a == null || b == null) return false;
if (a.constructor === RegExp || b.constructor === RegExp) {
- return (a.constructor === b.constructor) && (a.toString === b.toString);
+ return (a.constructor === b.constructor) && (a.toString() === b.toString());
}
if ((typeof a) !== 'object' || (typeof b) !== 'object' ||
(a === null) || (b === null))
@@ -205,7 +256,7 @@
function assertUnreachable(name_opt) {
// Fix this when we ditch the old test runner.
- var message = "Fail" + "ure: unreachable"
+ var message = "Fail" + "ure: unreachable";
if (name_opt) {
message += " - " + name_opt;
}
diff --git a/test/mjsunit/mul-exhaustive.js b/test/mjsunit/mul-exhaustive.js
index 452f933..12689db 100644
--- a/test/mjsunit/mul-exhaustive.js
+++ b/test/mjsunit/mul-exhaustive.js
@@ -26,41 +26,64 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var x;
-var y;
-var a;
-function f(a, y) {
- assertEquals(a, x * y);
- assertEquals(a, -x * -y);
- assertEquals(-a, -x * y);
- assertEquals(-a, x * -y);
- assertEquals(a, y * x);
- assertEquals(a, -y * -x);
- assertEquals(-a, y * -x);
- assertEquals(-a, -y * x);
+// Converts a number to string respecting -0.
+function stringify(n) {
+ if ((1 / n) === -Infinity) return "-0";
+ return String(n);
}
+function f(expected, y) {
+ function testEval(string, x, y) {
+ var mulFunction = Function("x, y", "return " + string);
+ return mulFunction(x, y);
+ }
+ function mulTest(expected, x, y) {
+ assertEquals(expected, x * y);
+ assertEquals(expected, testEval(stringify(x) + " * y", x, y));
+ assertEquals(expected, testEval("x * " + stringify(y), x, y));
+ assertEquals(expected, testEval(stringify(x) + " * " + stringify(y), x, y));
+ }
+ mulTest(expected, x, y);
+ mulTest(-expected, -x, y);
+ mulTest(-expected, x, -y);
+ mulTest(expected, -x, -y);
+ if (x === y) return; // Symmetric cases not necessary.
+ mulTest(expected, y, x);
+ mulTest(-expected, -y, x);
+ mulTest(-expected, y, -x);
+ mulTest(expected, -y, -x);
+}
+
+x = 0;
+f(0, 0);
x = 1;
+f(0, 0);
f(1, 1);
x = 2;
+f(0, 0);
f(2, 1);
f(4, 2);
x = 3;
+f(0, 0);
f(3, 1);
f(6, 2);
f(9, 3);
x = 4;
+f(0, 0);
f(4, 1);
f(8, 2);
f(12, 3);
f(16, 4);
x = 5;
+f(0, 0);
f(5, 1);
f(10, 2);
f(15, 3);
f(20, 4);
f(25, 5);
x = 7;
+f(0, 0);
f(7, 1);
f(14, 2);
f(21, 3);
@@ -68,6 +91,7 @@
f(35, 5);
f(49, 7);
x = 8;
+f(0, 0);
f(8, 1);
f(16, 2);
f(24, 3);
@@ -76,6 +100,7 @@
f(56, 7);
f(64, 8);
x = 9;
+f(0, 0);
f(9, 1);
f(18, 2);
f(27, 3);
@@ -85,6 +110,7 @@
f(72, 8);
f(81, 9);
x = 15;
+f(0, 0);
f(15, 1);
f(30, 2);
f(45, 3);
@@ -95,6 +121,7 @@
f(135, 9);
f(225, 15);
x = 16;
+f(0, 0);
f(16, 1);
f(32, 2);
f(48, 3);
@@ -106,6 +133,7 @@
f(240, 15);
f(256, 16);
x = 17;
+f(0, 0);
f(17, 1);
f(34, 2);
f(51, 3);
@@ -118,6 +146,7 @@
f(272, 16);
f(289, 17);
x = 31;
+f(0, 0);
f(31, 1);
f(62, 2);
f(93, 3);
@@ -131,6 +160,7 @@
f(527, 17);
f(961, 31);
x = 32;
+f(0, 0);
f(32, 1);
f(64, 2);
f(96, 3);
@@ -145,6 +175,7 @@
f(992, 31);
f(1024, 32);
x = 33;
+f(0, 0);
f(33, 1);
f(66, 2);
f(99, 3);
@@ -160,6 +191,7 @@
f(1056, 32);
f(1089, 33);
x = 63;
+f(0, 0);
f(63, 1);
f(126, 2);
f(189, 3);
@@ -176,6 +208,7 @@
f(2079, 33);
f(3969, 63);
x = 64;
+f(0, 0);
f(64, 1);
f(128, 2);
f(192, 3);
@@ -193,6 +226,7 @@
f(4032, 63);
f(4096, 64);
x = 65;
+f(0, 0);
f(65, 1);
f(130, 2);
f(195, 3);
@@ -211,6 +245,7 @@
f(4160, 64);
f(4225, 65);
x = 127;
+f(0, 0);
f(127, 1);
f(254, 2);
f(381, 3);
@@ -230,6 +265,7 @@
f(8255, 65);
f(16129, 127);
x = 128;
+f(0, 0);
f(128, 1);
f(256, 2);
f(384, 3);
@@ -250,6 +286,7 @@
f(16256, 127);
f(16384, 128);
x = 129;
+f(0, 0);
f(129, 1);
f(258, 2);
f(387, 3);
@@ -271,6 +308,7 @@
f(16512, 128);
f(16641, 129);
x = 255;
+f(0, 0);
f(255, 1);
f(510, 2);
f(765, 3);
@@ -293,6 +331,7 @@
f(32895, 129);
f(65025, 255);
x = 256;
+f(0, 0);
f(256, 1);
f(512, 2);
f(768, 3);
@@ -316,6 +355,7 @@
f(65280, 255);
f(65536, 256);
x = 257;
+f(0, 0);
f(257, 1);
f(514, 2);
f(771, 3);
@@ -340,6 +380,7 @@
f(65792, 256);
f(66049, 257);
x = 511;
+f(0, 0);
f(511, 1);
f(1022, 2);
f(1533, 3);
@@ -365,6 +406,7 @@
f(131327, 257);
f(261121, 511);
x = 512;
+f(0, 0);
f(512, 1);
f(1024, 2);
f(1536, 3);
@@ -391,6 +433,7 @@
f(261632, 511);
f(262144, 512);
x = 513;
+f(0, 0);
f(513, 1);
f(1026, 2);
f(1539, 3);
@@ -418,6 +461,7 @@
f(262656, 512);
f(263169, 513);
x = 1023;
+f(0, 0);
f(1023, 1);
f(2046, 2);
f(3069, 3);
@@ -446,6 +490,7 @@
f(524799, 513);
f(1046529, 1023);
x = 1024;
+f(0, 0);
f(1024, 1);
f(2048, 2);
f(3072, 3);
@@ -475,6 +520,7 @@
f(1047552, 1023);
f(1048576, 1024);
x = 1025;
+f(0, 0);
f(1025, 1);
f(2050, 2);
f(3075, 3);
@@ -505,6 +551,7 @@
f(1049600, 1024);
f(1050625, 1025);
x = 2047;
+f(0, 0);
f(2047, 1);
f(4094, 2);
f(6141, 3);
@@ -536,6 +583,7 @@
f(2098175, 1025);
f(4190209, 2047);
x = 2048;
+f(0, 0);
f(2048, 1);
f(4096, 2);
f(6144, 3);
@@ -568,6 +616,7 @@
f(4192256, 2047);
f(4194304, 2048);
x = 2049;
+f(0, 0);
f(2049, 1);
f(4098, 2);
f(6147, 3);
@@ -601,6 +650,7 @@
f(4196352, 2048);
f(4198401, 2049);
x = 4095;
+f(0, 0);
f(4095, 1);
f(8190, 2);
f(12285, 3);
@@ -635,6 +685,7 @@
f(8390655, 2049);
f(16769025, 4095);
x = 4096;
+f(0, 0);
f(4096, 1);
f(8192, 2);
f(12288, 3);
@@ -670,6 +721,7 @@
f(16773120, 4095);
f(16777216, 4096);
x = 4097;
+f(0, 0);
f(4097, 1);
f(8194, 2);
f(12291, 3);
@@ -706,6 +758,7 @@
f(16781312, 4096);
f(16785409, 4097);
x = 8191;
+f(0, 0);
f(8191, 1);
f(16382, 2);
f(24573, 3);
@@ -743,6 +796,7 @@
f(33558527, 4097);
f(67092481, 8191);
x = 8192;
+f(0, 0);
f(8192, 1);
f(16384, 2);
f(24576, 3);
@@ -781,6 +835,7 @@
f(67100672, 8191);
f(67108864, 8192);
x = 8193;
+f(0, 0);
f(8193, 1);
f(16386, 2);
f(24579, 3);
@@ -820,6 +875,7 @@
f(67117056, 8192);
f(67125249, 8193);
x = 16383;
+f(0, 0);
f(16383, 1);
f(32766, 2);
f(49149, 3);
@@ -860,6 +916,7 @@
f(134225919, 8193);
f(268402689, 16383);
x = 16384;
+f(0, 0);
f(16384, 1);
f(32768, 2);
f(49152, 3);
@@ -901,6 +958,7 @@
f(268419072, 16383);
f(268435456, 16384);
x = 16385;
+f(0, 0);
f(16385, 1);
f(32770, 2);
f(49155, 3);
@@ -943,6 +1001,7 @@
f(268451840, 16384);
f(268468225, 16385);
x = 32767;
+f(0, 0);
f(32767, 1);
f(65534, 2);
f(98301, 3);
@@ -986,6 +1045,7 @@
f(536887295, 16385);
f(1073676289, 32767);
x = 32768;
+f(0, 0);
f(32768, 1);
f(65536, 2);
f(98304, 3);
@@ -1030,6 +1090,7 @@
f(1073709056, 32767);
f(1073741824, 32768);
x = 32769;
+f(0, 0);
f(32769, 1);
f(65538, 2);
f(98307, 3);
@@ -1075,6 +1136,7 @@
f(1073774592, 32768);
f(1073807361, 32769);
x = 65535;
+f(0, 0);
f(65535, 1);
f(131070, 2);
f(196605, 3);
@@ -1121,6 +1183,7 @@
f(2147516415, 32769);
f(4294836225, 65535);
x = 65536;
+f(0, 0);
f(65536, 1);
f(131072, 2);
f(196608, 3);
@@ -1168,6 +1231,7 @@
f(4294901760, 65535);
f(4294967296, 65536);
x = 65537;
+f(0, 0);
f(65537, 1);
f(131074, 2);
f(196611, 3);
@@ -1216,6 +1280,7 @@
f(4295032832, 65536);
f(4295098369, 65537);
x = 131071;
+f(0, 0);
f(131071, 1);
f(262142, 2);
f(393213, 3);
@@ -1265,6 +1330,7 @@
f(8590000127, 65537);
f(17179607041, 131071);
x = 131072;
+f(0, 0);
f(131072, 1);
f(262144, 2);
f(393216, 3);
@@ -1315,6 +1381,7 @@
f(17179738112, 131071);
f(17179869184, 131072);
x = 131073;
+f(0, 0);
f(131073, 1);
f(262146, 2);
f(393219, 3);
@@ -1366,6 +1433,7 @@
f(17180000256, 131072);
f(17180131329, 131073);
x = 262143;
+f(0, 0);
f(262143, 1);
f(524286, 2);
f(786429, 3);
@@ -1418,6 +1486,7 @@
f(34359869439, 131073);
f(68718952449, 262143);
x = 262144;
+f(0, 0);
f(262144, 1);
f(524288, 2);
f(786432, 3);
@@ -1471,6 +1540,7 @@
f(68719214592, 262143);
f(68719476736, 262144);
x = 262145;
+f(0, 0);
f(262145, 1);
f(524290, 2);
f(786435, 3);
@@ -1525,6 +1595,7 @@
f(68719738880, 262144);
f(68720001025, 262145);
x = 524287;
+f(0, 0);
f(524287, 1);
f(1048574, 2);
f(1572861, 3);
@@ -1580,6 +1651,7 @@
f(137439215615, 262145);
f(274876858369, 524287);
x = 524288;
+f(0, 0);
f(524288, 1);
f(1048576, 2);
f(1572864, 3);
@@ -1636,6 +1708,7 @@
f(274877382656, 524287);
f(274877906944, 524288);
x = 524289;
+f(0, 0);
f(524289, 1);
f(1048578, 2);
f(1572867, 3);
@@ -1693,6 +1766,7 @@
f(274878431232, 524288);
f(274878955521, 524289);
x = 1048575;
+f(0, 0);
f(1048575, 1);
f(2097150, 2);
f(3145725, 3);
@@ -1751,6 +1825,7 @@
f(549756338175, 524289);
f(1099509530625, 1048575);
x = 1048576;
+f(0, 0);
f(1048576, 1);
f(2097152, 2);
f(3145728, 3);
@@ -1810,6 +1885,7 @@
f(1099510579200, 1048575);
f(1099511627776, 1048576);
x = 1048577;
+f(0, 0);
f(1048577, 1);
f(2097154, 2);
f(3145731, 3);
@@ -1870,6 +1946,7 @@
f(1099512676352, 1048576);
f(1099513724929, 1048577);
x = 2097151;
+f(0, 0);
f(2097151, 1);
f(4194302, 2);
f(6291453, 3);
@@ -1931,6 +2008,7 @@
f(2199024304127, 1048577);
f(4398042316801, 2097151);
x = 2097152;
+f(0, 0);
f(2097152, 1);
f(4194304, 2);
f(6291456, 3);
@@ -1993,6 +2071,7 @@
f(4398044413952, 2097151);
f(4398046511104, 2097152);
x = 2097153;
+f(0, 0);
f(2097153, 1);
f(4194306, 2);
f(6291459, 3);
@@ -2056,6 +2135,7 @@
f(4398048608256, 2097152);
f(4398050705409, 2097153);
x = 4194303;
+f(0, 0);
f(4194303, 1);
f(8388606, 2);
f(12582909, 3);
@@ -2120,6 +2200,7 @@
f(8796095119359, 2097153);
f(17592177655809, 4194303);
x = 4194304;
+f(0, 0);
f(4194304, 1);
f(8388608, 2);
f(12582912, 3);
@@ -2185,6 +2266,7 @@
f(17592181850112, 4194303);
f(17592186044416, 4194304);
x = 4194305;
+f(0, 0);
f(4194305, 1);
f(8388610, 2);
f(12582915, 3);
@@ -2251,6 +2333,7 @@
f(17592190238720, 4194304);
f(17592194433025, 4194305);
x = 8388607;
+f(0, 0);
f(8388607, 1);
f(16777214, 2);
f(25165821, 3);
@@ -2318,6 +2401,7 @@
f(35184376283135, 4194305);
f(70368727400449, 8388607);
x = 8388608;
+f(0, 0);
f(8388608, 1);
f(16777216, 2);
f(25165824, 3);
@@ -2386,6 +2470,7 @@
f(70368735789056, 8388607);
f(70368744177664, 8388608);
x = 8388609;
+f(0, 0);
f(8388609, 1);
f(16777218, 2);
f(25165827, 3);
@@ -2455,6 +2540,7 @@
f(70368752566272, 8388608);
f(70368760954881, 8388609);
x = 16777215;
+f(0, 0);
f(16777215, 1);
f(33554430, 2);
f(50331645, 3);
@@ -2525,6 +2611,7 @@
f(140737496743935, 8388609);
f(281474943156225, 16777215);
x = 16777216;
+f(0, 0);
f(16777216, 1);
f(33554432, 2);
f(50331648, 3);
@@ -2596,6 +2683,7 @@
f(281474959933440, 16777215);
f(281474976710656, 16777216);
x = 16777217;
+f(0, 0);
f(16777217, 1);
f(33554434, 2);
f(50331651, 3);
@@ -2668,6 +2756,7 @@
f(281474993487872, 16777216);
f(281475010265089, 16777217);
x = 33554431;
+f(0, 0);
f(33554431, 1);
f(67108862, 2);
f(100663293, 3);
@@ -2741,6 +2830,7 @@
f(562949970198527, 16777217);
f(1125899839733761, 33554431);
x = 33554432;
+f(0, 0);
f(33554432, 1);
f(67108864, 2);
f(100663296, 3);
@@ -2815,6 +2905,7 @@
f(1125899873288192, 33554431);
f(1125899906842624, 33554432);
x = 33554433;
+f(0, 0);
f(33554433, 1);
f(67108866, 2);
f(100663299, 3);
@@ -2890,6 +2981,7 @@
f(1125899940397056, 33554432);
f(1125899973951489, 33554433);
x = 67108863;
+f(0, 0);
f(67108863, 1);
f(134217726, 2);
f(201326589, 3);
@@ -2962,6 +3054,7 @@
f(1125899890065408, 16777216);
f(1125899957174271, 16777217);
x = 67108864;
+f(0, 0);
f(67108864, 1);
f(134217728, 2);
f(201326592, 3);
@@ -3034,6 +3127,7 @@
f(1125899906842624, 16777216);
f(1125899973951488, 16777217);
x = 67108865;
+f(0, 0);
f(67108865, 1);
f(134217730, 2);
f(201326595, 3);
@@ -3106,6 +3200,7 @@
f(1125899923619840, 16777216);
f(1125899990728705, 16777217);
x = 134217727;
+f(0, 0);
f(134217727, 1);
f(268435454, 2);
f(402653181, 3);
@@ -3175,6 +3270,7 @@
f(1125899898454016, 8388608);
f(1125900032671743, 8388609);
x = 134217728;
+f(0, 0);
f(134217728, 1);
f(268435456, 2);
f(402653184, 3);
@@ -3244,6 +3340,7 @@
f(1125899906842624, 8388608);
f(1125900041060352, 8388609);
x = 134217729;
+f(0, 0);
f(134217729, 1);
f(268435458, 2);
f(402653187, 3);
@@ -3313,6 +3410,7 @@
f(1125899915231232, 8388608);
f(1125900049448961, 8388609);
x = 268435455;
+f(0, 0);
f(268435455, 1);
f(536870910, 2);
f(805306365, 3);
@@ -3379,6 +3477,7 @@
f(1125899902648320, 4194304);
f(1125900171083775, 4194305);
x = 268435456;
+f(0, 0);
f(268435456, 1);
f(536870912, 2);
f(805306368, 3);
@@ -3445,6 +3544,7 @@
f(1125899906842624, 4194304);
f(1125900175278080, 4194305);
x = 268435457;
+f(0, 0);
f(268435457, 1);
f(536870914, 2);
f(805306371, 3);
@@ -3511,6 +3611,7 @@
f(1125899911036928, 4194304);
f(1125900179472385, 4194305);
x = 536870911;
+f(0, 0);
f(536870911, 1);
f(1073741822, 2);
f(1610612733, 3);
@@ -3574,6 +3675,7 @@
f(1125899904745472, 2097152);
f(1125900441616383, 2097153);
x = 536870912;
+f(0, 0);
f(536870912, 1);
f(1073741824, 2);
f(1610612736, 3);
@@ -3637,6 +3739,7 @@
f(1125899906842624, 2097152);
f(1125900443713536, 2097153);
x = 536870913;
+f(0, 0);
f(536870913, 1);
f(1073741826, 2);
f(1610612739, 3);
@@ -3700,6 +3803,7 @@
f(1125899908939776, 2097152);
f(1125900445810689, 2097153);
x = 1073741823;
+f(0, 0);
f(1073741823, 1);
f(2147483646, 2);
f(3221225469, 3);
@@ -3760,6 +3864,7 @@
f(1125899905794048, 1048576);
f(1125900979535871, 1048577);
x = 1073741824;
+f(0, 0);
f(1073741824, 1);
f(2147483648, 2);
f(3221225472, 3);
@@ -3820,6 +3925,7 @@
f(1125899906842624, 1048576);
f(1125900980584448, 1048577);
x = 1073741825;
+f(0, 0);
f(1073741825, 1);
f(2147483650, 2);
f(3221225475, 3);
@@ -3880,6 +3986,7 @@
f(1125899907891200, 1048576);
f(1125900981633025, 1048577);
x = 2147483647;
+f(0, 0);
f(2147483647, 1);
f(4294967294, 2);
f(6442450941, 3);
@@ -3937,6 +4044,7 @@
f(1125899906318336, 524288);
f(1125902053801983, 524289);
x = 2147483648;
+f(0, 0);
f(2147483648, 1);
f(4294967296, 2);
f(6442450944, 3);
@@ -3994,6 +4102,7 @@
f(1125899906842624, 524288);
f(1125902054326272, 524289);
x = 2147483649;
+f(0, 0);
f(2147483649, 1);
f(4294967298, 2);
f(6442450947, 3);
@@ -4051,6 +4160,7 @@
f(1125899907366912, 524288);
f(1125902054850561, 524289);
x = 4294967295;
+f(0, 0);
f(4294967295, 1);
f(8589934590, 2);
f(12884901885, 3);
@@ -4105,6 +4215,7 @@
f(1125899906580480, 262144);
f(1125904201547775, 262145);
x = 4294967296;
+f(0, 0);
f(4294967296, 1);
f(8589934592, 2);
f(12884901888, 3);
@@ -4159,6 +4270,7 @@
f(1125899906842624, 262144);
f(1125904201809920, 262145);
x = 4294967297;
+f(0, 0);
f(4294967297, 1);
f(8589934594, 2);
f(12884901891, 3);
@@ -4213,6 +4325,7 @@
f(1125899907104768, 262144);
f(1125904202072065, 262145);
x = 8589934591;
+f(0, 0);
f(8589934591, 1);
f(17179869182, 2);
f(25769803773, 3);
@@ -4264,6 +4377,7 @@
f(1125899906711552, 131072);
f(1125908496646143, 131073);
x = 8589934592;
+f(0, 0);
f(8589934592, 1);
f(17179869184, 2);
f(25769803776, 3);
@@ -4315,6 +4429,7 @@
f(1125899906842624, 131072);
f(1125908496777216, 131073);
x = 8589934593;
+f(0, 0);
f(8589934593, 1);
f(17179869186, 2);
f(25769803779, 3);
@@ -4366,6 +4481,7 @@
f(1125899906973696, 131072);
f(1125908496908289, 131073);
x = 17179869183;
+f(0, 0);
f(17179869183, 1);
f(34359738366, 2);
f(51539607549, 3);
@@ -4414,6 +4530,7 @@
f(1125899906777088, 65536);
f(1125917086646271, 65537);
x = 17179869184;
+f(0, 0);
f(17179869184, 1);
f(34359738368, 2);
f(51539607552, 3);
@@ -4462,6 +4579,7 @@
f(1125899906842624, 65536);
f(1125917086711808, 65537);
x = 17179869185;
+f(0, 0);
f(17179869185, 1);
f(34359738370, 2);
f(51539607555, 3);
diff --git a/test/mjsunit/negate-zero.js b/test/mjsunit/negate-zero.js
index 31d460a..558be94 100644
--- a/test/mjsunit/negate-zero.js
+++ b/test/mjsunit/negate-zero.js
@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function IsNegativeZero(x) {
- assertEquals(0, x);
+ assertTrue(x == 0); // Is 0 or -0.
var y = 1 / x;
assertFalse(isFinite(y));
return y < 0;
diff --git a/test/mjsunit/object-freeze.js b/test/mjsunit/object-freeze.js
index 15e19ab..3eefffd 100644
--- a/test/mjsunit/object-freeze.js
+++ b/test/mjsunit/object-freeze.js
@@ -70,12 +70,8 @@
assertFalse(Object.isExtensible(obj));
assertTrue(Object.isFrozen(obj));
-try {
- obj.foo = 42;
- assertUnreachable();
-} catch(e) {
- assertTrue(/object is not extensible/.test(e));
-}
+obj.foo = 42;
+assertEquals(obj.foo, undefined);
desc = Object.getOwnPropertyDescriptor(obj, 'x');
assertFalse(desc.writable);
@@ -88,7 +84,7 @@
assertEquals("foobar", desc.value);
// Make sure that even if we try overwrite a value that is not writable, it is
-// not changed.
+// not changed.
obj.x = "tete";
assertEquals(42, obj.x);
obj.x = { get: function() {return 43}, set: function() {} };
@@ -118,12 +114,8 @@
assertEquals(set, desc.set);
assertEquals(get, desc.get);
-try {
- obj2.foo = 42;
- assertUnreachable();
-} catch(e) {
- assertTrue(/object is not extensible/.test(e));
-}
+obj2.foo = 42;
+assertEquals(obj2.foo, undefined);
// Test freeze on arrays.
diff --git a/test/mjsunit/object-prevent-extensions.js b/test/mjsunit/object-prevent-extensions.js
index ebc2cfa6..dc32342 100644
--- a/test/mjsunit/object-prevent-extensions.js
+++ b/test/mjsunit/object-prevent-extensions.js
@@ -35,22 +35,11 @@
// Make sure the is_extensible flag is set.
assertFalse(Object.isExtensible(obj1));
-// Try adding a new property.
-try {
- obj1.x = 42;
- assertUnreachable();
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
+obj1.x = 42;
assertEquals(undefined, obj1.x);
// Try adding a new element.
-try {
- obj1[1] = 42;
- assertUnreachable();
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
+obj1[1] = 42;
assertEquals(undefined, obj1[1]);
@@ -64,25 +53,14 @@
Object.preventExtensions(obj2);
assertEquals(42, obj2.x);
-try {
- obj2.y = 42;
- assertUnreachable();
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
-
+obj2.y = 42;
// obj2.y should still be undefined.
assertEquals(undefined, obj2.y);
// Make sure we can still write values to obj.x.
obj2.x = 43;
assertEquals(43, obj2.x)
-try {
- obj2.y = new function() { return 42; };
- assertUnreachable();
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
+obj2.y = new function() { return 42; };
// obj2.y should still be undefined.
assertEquals(undefined, obj2.y);
assertEquals(43, obj2.x)
@@ -97,12 +75,7 @@
assertEquals(undefined, obj2.y);
assertEquals(43, obj2.x);
-try {
- obj2[1] = 42;
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
-
+obj2[1] = 42;
assertEquals(undefined, obj2[1]);
var arr = new Array();
@@ -110,12 +83,7 @@
Object.preventExtensions(arr);
-try {
- arr[2] = 42;
- assertUnreachable();
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
+arr[2] = 42;
assertEquals(10, arr[1]);
// We should still be able to change exiting elements.
@@ -134,12 +102,7 @@
child.y = 42;
// This should have no influence on the parent class.
-try {
- parent.y = 29;
- assertUnreachable();
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
+parent.y = 29;
// Test that attributes on functions are also handled correctly.
@@ -149,9 +112,5 @@
Object.preventExtensions(foo);
-try {
- foo.x = 29;
- assertUnreachable();
-} catch (e) {
- assertTrue(/object is not extensible/.test(e));
-}
+foo.x = 29;
+assertEquals(undefined, foo.x);
diff --git a/test/mjsunit/object-seal.js b/test/mjsunit/object-seal.js
index 9e7f44b..3ce2367 100644
--- a/test/mjsunit/object-seal.js
+++ b/test/mjsunit/object-seal.js
@@ -75,12 +75,8 @@
assertFalse(Object.isFrozen(obj));
// We should not allow new properties to be added.
-try {
- obj.foo = 42;
- assertUnreachable();
-} catch(e) {
- assertTrue(/object is not extensible/.test(e));
-}
+obj.foo = 42;
+assertEquals(obj.foo, undefined);
desc = Object.getOwnPropertyDescriptor(obj, 'x');
assertTrue(desc.writable);
@@ -125,13 +121,8 @@
assertEquals(set, desc.set);
assertEquals(get, desc.get);
-try {
- obj2.foo = 42;
- assertUnreachable();
-} catch(e) {
- assertTrue(/object is not extensible/.test(e));
-}
-
+obj2.foo = 42;
+assertEquals(obj2.foo, undefined);
// Test seal on arrays.
var arr = new Array(42,43);
diff --git a/test/mjsunit/regress/regress-create-exception.js b/test/mjsunit/regress/regress-create-exception.js
index 2119ce2..d3face9 100644
--- a/test/mjsunit/regress/regress-create-exception.js
+++ b/test/mjsunit/regress/regress-create-exception.js
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --max-new-space-size=256
+"use strict";
// Check for GC bug constructing exceptions.
var v = [1, 2, 3, 4]
diff --git a/test/mjsunit/regress/regress-lazy-deopt-reloc.js b/test/mjsunit/regress/regress-lazy-deopt-reloc.js
new file mode 100644
index 0000000..f1fe6d5
--- /dev/null
+++ b/test/mjsunit/regress/regress-lazy-deopt-reloc.js
@@ -0,0 +1,52 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Do not generate debug code since that will space things differently
+// in the generated code.
+// Flags: --allow-natives-syntax --expose-gc --nodebug-code
+
+// Regression test for issue where we did not pad the relocation
+// information enough to have room for lazy deoptimization.
+
+function kaboom() {
+ var a = function () {},
+ b = function () {},
+ c, d = function () { var d = []; },
+ e = function () { var e = {}; };
+ c = function () { d(); b(); };
+ return function (x, y) {
+ c();
+ a();
+ return function f() { }({});
+ };
+}
+
+kaboom();
+
+%DeoptimizeFunction(kaboom);
+
+gc();
diff --git a/test/mjsunit/smi-negative-zero.js b/test/mjsunit/smi-negative-zero.js
index ea2fa5a..1bab920 100644
--- a/test/mjsunit/smi-negative-zero.js
+++ b/test/mjsunit/smi-negative-zero.js
@@ -109,5 +109,5 @@
return -x;
}
-assertEquals(0, foo(x));
-assertEquals(0, foo(x));
+assertEquals(-0, foo(x));
+assertEquals(-0, foo(x));
diff --git a/test/mjsunit/str-to-num.js b/test/mjsunit/str-to-num.js
index 28e98d9..bbfa7d3 100644
--- a/test/mjsunit/str-to-num.js
+++ b/test/mjsunit/str-to-num.js
@@ -190,7 +190,7 @@
assertEquals(Infinity, toNumber("1e999"), "1e999");
assertEquals(-Infinity, toNumber("-1e999"));
assertEquals(0, toNumber("1e-999"));
-assertEquals(0, toNumber("-1e-999"));
+assertEquals(-0, toNumber("-1e-999"));
assertEquals(Infinity, 1 / toNumber("1e-999"), "1e-999");
assertEquals(-Infinity, 1 / toNumber("-1e-999"));
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
index 1f7666f..84ccb30 100644
--- a/test/mjsunit/strict-mode.js
+++ b/test/mjsunit/strict-mode.js
@@ -983,7 +983,10 @@
function CheckPill(pill) {
assertEquals("function", typeof pill);
assertInstanceof(pill, Function);
- assertThrows(function() { pill.property = "value"; }, TypeError);
+ pill.property = "value";
+ assertEquals(pill.value, undefined);
+ assertThrows(function() { 'use strict'; pill.property = "value"; },
+ TypeError);
assertThrows(pill, TypeError);
assertEquals(pill.prototype, (function(){}).prototype);
var d = Object.getOwnPropertyDescriptor(pill, "prototype");
diff --git a/test/test262/README b/test/test262/README
new file mode 100644
index 0000000..6d9e56e
--- /dev/null
+++ b/test/test262/README
@@ -0,0 +1,16 @@
+This directory contains code for binding the test262 test suite
+into the v8 test harness. To use the tests check out the test262
+tests from
+
+ http://hg.ecmascript.org/tests/test262
+
+at revision 62 as 'data' in this directory. Using later version
+may be possible but the tests are only known to pass (and indeed run)
+with that revision.
+
+hg clone -r 62 http://hg.ecmascript.org/tests/test262 data
+
+If you do update to a newer revision you may have to change the test
+harness adapter code since it uses internal functionality from the
+harness that comes bundled with the tests. You will most likely also
+have to update the test expectation file.
diff --git a/test/test262/harness-adapt.js b/test/test262/harness-adapt.js
new file mode 100644
index 0000000..b52afdb
--- /dev/null
+++ b/test/test262/harness-adapt.js
@@ -0,0 +1,80 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function fnGlobalObject() { return (function() { return this; })(); }
+
+var ES5Harness = (function() {
+ var currentTest = {};
+ var $this = this;
+
+ function Test262Error(id, path, description, codeString,
+ preconditionString, result, error) {
+ this.id = id;
+ this.path = path;
+ this.description = description;
+ this.result = result;
+ this.error = error;
+ this.code = codeString;
+ this.pre = preconditionString;
+ }
+
+ Test262Error.prototype.toString = function() {
+ return this.result;
+ }
+
+ function registerTest(test) {
+ if (!(test.precondition && !test.precondition())) {
+ var error;
+ try {
+ var res = test.test.call($this);
+ } catch(e) {
+ print(e);
+ res = 'fail'; error = e;
+ }
+ var retVal = /^s/i.test(test.id)
+ ? (res === true || typeof res == 'undefined' ? 'pass' : 'fail')
+ : (res === true ? 'pass' : 'fail');
+
+ if (retVal != 'pass') {
+ throw new Test262Error(
+ test.id,
+ test.path,
+ test.description,
+ test.test.toString(),
+ (test.precondition !== undefined)
+ ? test.precondition.toString()
+ : '',
+ retVal,
+ error);
+ }
+ }
+ }
+
+ return {
+ registerTest: registerTest
+ }
+})();
diff --git a/test/test262/test262.status b/test/test262/test262.status
new file mode 100644
index 0000000..bdc8b9c
--- /dev/null
+++ b/test/test262/test262.status
@@ -0,0 +1,1506 @@
+# Copyright 2011 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#
+# ietestcenter tests.
+#
+
+prefix ietestcenter
+
+# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
+# Names in UTF8: class (class)
+7.6-30: FAIL
+# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
+# Names in UTF8: extends (extends)
+7.6-31: FAIL
+# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
+# Names in UTF8: \u0065\u006e\u0075\u006d (enum)
+7.6-32: FAIL
+# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
+# Names in UTF8: \u0073uper (super)
+7.6-33: FAIL
+# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
+# Names in UTF8: expor\u0074 (export)
+7.6-35: FAIL
+# BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
+# Names in UTF8: \u0069\u006d\u0070\u006f\u0072\u0074 (import)
+7.6-36: FAIL
+# Invalid test: https://bugs.ecmascript.org/show_bug.cgi?id=76
+10.4.2-2-c-1: FAIL
+# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
+# when using Greater-than operator: valueOf > valueOf
+11.8.2-1: FAIL
+# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
+# when using Greater-than operator: valueOf > toString
+11.8.2-2: FAIL
+# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
+# when using Greater-than operator: toString > valueOf
+11.8.2-3: FAIL
+# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
+# when using Greater-than operator: toString > toString
+11.8.2-4: FAIL
+# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
+# enforced when using Less-than-or-equal operator: valueOf <= valueOf
+11.8.3-1: FAIL
+# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
+# enforced when using Less-than-or-equal operator: valueOf <= toString
+11.8.3-2: FAIL
+# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
+# enforced when using Less-than-or-equal operator: toString <= valueOf
+11.8.3-3: FAIL
+# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
+# enforced when using Less-than-or-equal operator: toString <= toString
+11.8.3-4: FAIL
+# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
+# enforced when using Less-than-or-equal operator: valueOf <= valueOf
+11.8.3-5: FAIL
+# BUG: Global.NaN is a data property with default attribute values
+15.1.1.1-0: FAIL
+# BUG: Global.Infinity is a data property with default attribute values
+15.1.1.2-0: FAIL
+# BUG: Global.undefined is a data property with default attribute values
+15.1.1.3-0: FAIL
+# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
+# for properties on built-ins (Global.NaN)
+15.2.3.3-4-178: FAIL
+# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
+# for properties on built-ins (Global.Infinity)
+15.2.3.3-4-179: FAIL
+# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
+# for properties on built-ins (Global.undefined)
+15.2.3.3-4-180: FAIL
+# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
+# for properties on built-ins (RegExp.prototype.source)
+# There is no RegExp.prototype.source
+15.2.3.3-4-212: FAIL
+# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
+# for properties on built-ins (RegExp.prototype.global)
+# There is no RegExp.prototype.global
+15.2.3.3-4-213: FAIL
+# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
+# for properties on built-ins (RegExp.prototype.ignoreCase)
+# There is no RegExp.prototype.ignoreCase
+15.2.3.3-4-214: FAIL
+# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
+# for properties on built-ins (RegExp.prototype.multiline)
+15.2.3.3-4-215: FAIL
+# Bug? Object.create - 'set' property of one property in 'Properties'
+# is not present (8.10.5 step 8)
+# V8 throws.
+15.2.3.5-4-267: FAIL
+# Bug? Object.create - 'set' property of one property in 'Properties'
+# is undefined (8.10.5 step 8.b)
+# V8 throws.
+15.2.3.5-4-292: FAIL
+# Bug? Object.defineProperty - 'set' property in 'Attributes' is not
+# present (8.10.5 step 8)
+# V8 throws.
+15.2.3.6-3-236: FAIL
+# Bug? Object.defineProperty - 'set' property in 'Attributes' is own
+# accessor property without a get function (8.10.5 step 8.a)
+# V8 throws.
+15.2.3.6-3-245: FAIL
+# Bug? Object.defineProperty - 'set' property in 'Attributes' is own
+# accessor property(without a get function) that overrides an inherited
+# accessor property (8.10.5 step 8.a)
+# V8 throws.
+15.2.3.6-3-246: FAIL
+# Bug? Object.defineProperty - 'set' property in 'Attributes' is an
+# inherited accessor property without a get function (8.10.5 step 8.a)
+# V8 throws.
+15.2.3.6-3-247: FAIL
+# Bug? Object.defineProperty - value of 'set' property in 'Attributes'
+# is undefined (8.10.5 step 8.b)
+# V8 throws.
+15.2.3.6-3-261: FAIL
+# Bug? Object.defineProperty - Update [[Enumerable]] attribute of 'name'
+# property to true successfully when [[Enumerable]] attribute of 'name'
+# is false and [[Configurable]] attribute of 'name' is true, the 'desc'
+# is a generic descriptor which only contains [[Enumerable]] attribute
+# as true, 'name' property is an index data property (8.12.9 step 8)
+15.2.3.6-4-82-18: FAIL
+# Bug? Object.defineProperty - Update [[Enumerable]] attribute of 'name'
+# property to false successfully when [[Enumerable]] and [[Configurable]]
+# attributes of 'name' property are true, the 'desc' is a generic
+# descriptor which only contains [Enumerable]] attribute as false and
+# 'name' property is an index accessor property (8.12.9 step 8)
+15.2.3.6-4-82-19: FAIL
+# Bug? Object.defineProperty - Update [[Enumerable]] attribute of 'name'
+# property to false successfully when [[Enumerable]] and [[Configurable]]
+# attributes of 'name' property are true, the 'desc' is a generic
+# descriptor which contains [Enumerable]] attribute as false and
+# [[Configurable]] property is true, 'name' property is an index accessor
+# property (8.12.9 step 8)
+15.2.3.6-4-82-20: FAIL
+# Bug? Object.defineProperty - Update [[Configurable]] attribute of 'name'
+# property to false successfully when [[Enumerable]] and [[Configurable]]
+# attributes of 'name' property are true, the 'desc' is a generic
+# descriptor which only contains [[Configurable]] attribute as false,
+# 'name' property is an index accessor property (8.12.9 step 8)
+15.2.3.6-4-82-21: FAIL
+# Bug? Object.defineProperty - Update [[Configurable]] attribute of 'name'
+# property to false successfully when [[Enumerable]] and [[Configurable]]
+# attributes of 'name' property are true, the 'desc' is a generic
+# descriptor which contains [[Enumerable]] attribute as true and
+# [[Configurable]] attribute is false, 'name' property is an index accessor
+# property (8.12.9 step 8)
+15.2.3.6-4-82-22: FAIL
+# Bug? Object.defineProperty - Update [[Enumerable]] and [[Configurable]]
+# attributes of 'name' property to false successfully when [[Enumerable]]
+# and [[Configurable]] attributes of 'name' property are true, the 'desc'
+# is a generic descriptor which contains [[Enumerable]] and
+# [[Configurable]] attributes as false, 'name' property is an index
+# accessor property (8.12.9 step 8)
+15.2.3.6-4-82-23: FAIL
+# Bug? Object.defineProperty - Update [[Enumerable]] attributes of 'name'
+# property to true successfully when [[Enumerable]] attribute of 'name' is
+# false and [[Configurable]] attribute of 'name' is true, the 'desc' is a
+# generic descriptor which only contains [[Enumerable]] attribute as true,
+# 'name' property is an index accessor property (8.12.9 step 8)
+15.2.3.6-4-82-24: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, test the length property of 'O'
+# is own data property (15.4.5.1 step 1)
+15.2.3.6-4-116: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, test the length property of 'O'
+# is own data property that overrides an inherited data property (15.4.5.1
+# step 1)
+15.2.3.6-4-117: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test that RangeError exception is thrown when [[Value]] field of
+# 'desc' is undefined (15.4.5.1 step 3.c)
+15.2.3.6-4-125: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is null (15.4.5.1 step 3.c)
+15.2.3.6-4-126: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is a boolean with value false
+# (15.4.5.1 step 3.c)
+15.2.3.6-4-127: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is a boolean with value true
+# (15.4.5.1 step 3.c)
+15.2.3.6-4-128: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is not thrown when the [[Value]] field of
+# 'desc' is 0 (15.4.5.1 step 3.c)
+15.2.3.6-4-129: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is not thrown when the [[Value]] field of
+# 'desc' is +0 (15.4.5.1 step 3.c)
+15.2.3.6-4-130: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is not thrown when the [[Value]] field of
+# 'desc' is -0 (15.4.5.1 step 3.c)
+15.2.3.6-4-131: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is not thrown when the [[Value]] field of
+# 'desc' is a positive number (15.4.5.1 step 3.c)
+15.2.3.6-4-132: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is a negative number (15.4.5.1 step 3.c)
+15.2.3.6-4-133: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is +Infinity (15.4.5.1 step 3.c)
+15.2.3.6-4-134: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is -Infinity (15.4.5.1 step 3.c)
+15.2.3.6-4-135: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is NaN (15.4.5.1 step 3.c)
+15.2.3.6-4-136: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is not thrown when the [[Value]] field of
+# 'desc' is a string containing a positive number (15.4.5.1 step 3.c)
+15.2.3.6-4-137: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is a string containing a negative number (15.4.5.1 step 3.c)
+15.2.3.6-4-138: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is a string containing a decimal number (15.4.5.1 step 3.c)
+15.2.3.6-4-139: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is a string containing +Infinity (15.4.5.1 step 3.c)
+15.2.3.6-4-140: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is a string containing -Infinity (15.4.5.1 step 3.c)
+15.2.3.6-4-141: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is a string containing an
+# exponential number (15.4.5.1 step 3.c)
+15.2.3.6-4-142: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is a string containing a hex
+# number (15.4.5.1 step 3.c)
+15.2.3.6-4-143: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is a string containing a number
+# with leading zeros (15.4.5.1 step 3.c)
+15.2.3.6-4-144: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError exception is thrown when the [[Value]] field of
+# 'desc' is a string which doesn't convert to a number (15.4.5.1 step 3.c)
+15.2.3.6-4-145: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is an object which has an own
+# toString method (15.4.5.1 step 3.c)
+15.2.3.6-4-146: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is an Object which has an own
+# valueOf method (15.4.5.1 step 3.c)
+15.2.3.6-4-147: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is an Object which has an own
+# valueOf method that returns an object and toString method that returns a
+# string (15.4.5.1 step 3.c)
+15.2.3.6-4-148: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is an Object which has an own
+# toString and valueOf method (15.4.5.1 step 3.c)
+15.2.3.6-4-149: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test TypeError is thrown when the [[Value]] field of 'desc' is an
+# Object that both toString and valueOf wouldn't return primitive value
+# (15.4.5.1 step 3.c)
+15.2.3.6-4-150: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', and the [[Value]] field of 'desc' is an Object with an own toString
+# method and an inherited valueOf method (15.4.5.1 step 3.c), test that the
+# inherited valueOf method is used
+15.2.3.6-4-151: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError is thrown when the [[Value]] field of 'desc' is a
+# positive non-integer values (15.4.5.1 step 3.c)
+15.2.3.6-4-152: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length prosperty
+# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is a
+# negative non-integer values (15.4.5.1 step 3.c)
+15.2.3.6-4-153: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 2
+# (15.4.5.1 step 3.c)
+15.2.3.6-4-154: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 1
+# (15.4.5.1 step 3.c)
+15.2.3.6-4-155: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
+# boundary value 2^32 (15.4.5.1 step 3.c)
+15.2.3.6-4-156: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
+# boundary value 2^32 + 1 (15.4.5.1 step 3.c)
+15.2.3.6-4-157: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', set the [[Value]] field of 'desc' to a value greater than the
+# existing value of length (15.4.5.1 step 3.f)
+15.2.3.6-4-159: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', set the [[Value]] field of 'desc' to a value lesser than the
+# existing value of length and test that indexes beyond the new length are
+# deleted(15.4.5.1 step 3.f)
+15.2.3.6-4-161: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to true after deleting properties with large index named if the
+# [[Writable]] field of 'desc' is absent (15.4.5.1 step 3.h)
+15.2.3.6-4-165: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to true after deleting properties with large index named if the
+# [[Writable]] field of 'desc' is true (15.4.5.1 step 3.h)
+15.2.3.6-4-166: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to false after deleting properties with large index named if the
+# [[Writable]] field of 'desc' is false (15.4.5.1 step 3.i.ii)
+15.2.3.6-4-167: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', whose writable attribute is being changed to false and the [[Value]]
+# field of 'desc' is less than value of the length property and also lesser
+# than an index of the array which is set to configurable:false, test that
+# new length is set to a value greater than the non-deletable index by 1,
+# writable attribute of length is set to false and TypeError exception is
+# thrown (15.4.5.1 step 3.i.iii)
+15.2.3.6-4-168: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property and also lesser than an index of the array which is set to
+# configurable: false, test that new length is set to a value greater than
+# the non-deletable index by 1, and TypeError is thrown (15.4.5.1 step
+# 3.l.i)
+15.2.3.6-4-169: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property and also lesser than an index of the array which is set to
+# configurable: false, test that new length is set to a value greater than
+# the non-deletable index by 1, writable attribute of length is set to
+# false and TypeError exception is thrown (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-170: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of an inherited data
+# property with large index named in 'O' can't stop deleting index named
+# properties (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-171: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own data property with
+# large index named in 'O' that overrides an inherited data property can
+# stop deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-172: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own data property with
+# large index named in 'O' that overrides an inherited accessor property
+# can stop deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-173: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own accessor property
+# with large index named in 'O' can stop deleting index named properties
+# (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-174: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of an inherited accessor
+# property with large index named in 'O' can't stop deleting index named
+# properties (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-175: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own accessor property
+# with large index named in 'O' that overrides an inherited data property
+# can stop deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-176: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own accessor property
+# with large index named in 'O' that overrides an inherited accessor
+# property can stop deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-177: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the configurable large index named property of 'O' is
+# deleted (15.4.5.1 step 3.l.ii)
+15.2.3.6-4-178: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is greater than value of the length
+# property, test value of the length property is same as [[Value]]
+# (15.4.5.1 step 3.l.iii.1)
+15.2.3.6-4-179-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to false at last when the [[Writable]] field of 'desc' is false and 'O'
+# doesn't contain non-configurable large index named property (15.4.5.1
+# step 3.m)
+15.2.3.6-4-181: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, 'name' is boundary value 2^32 - 2 (15.4.5.1 step 4.a)
+15.2.3.6-4-183: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, test TypeError is thrown if the [[Writable]] attribute of the
+# length property in 'O' is false and value of 'name' equals to value of
+# the length property (15.4.5.1 step 4.b)
+15.2.3.6-4-188: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, test TypeError is thrown if the [[Writable]] attribute of the
+# length property in 'O' is false and value of 'name' is greater than value
+# of the length property (15.4.5.1 step 4.b)
+15.2.3.6-4-189: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, 'desc' is accessor descriptor, test updating all attribute
+# values of 'name' (15.4.5.1 step 4.c)
+15.2.3.6-4-209: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, 'name' is accessor property and assignment to the accessor
+# property, fails to convert accessor property from accessor property to
+# data property (15.4.5.1 step 4.c)
+15.2.3.6-4-243-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, name is accessor property and 'desc' is accessor descriptor,
+# test updating the [[Enumerable]] attribute value of 'name' (15.4.5.1 step
+# 4.c)
+15.2.3.6-4-271: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, name is accessor property and 'desc' is accessor descriptor,
+# test updating the [[Configurable]] attribute value of 'name' (15.4.5.1
+# step 4.c)
+15.2.3.6-4-272: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, name is accessor property and 'desc' is accessor descriptor,
+# test updating multiple attribute values of 'name' (15.4.5.1 step 4.c)
+15.2.3.6-4-273: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, test the length property of 'O' is set as ToUint32('name') + 1
+# if ToUint32('name') equals to value of the length property in 'O'
+# (15.4.5.1 step 4.e.ii)
+15.2.3.6-4-275: FAIL
+# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
+# property, test the length property of 'O' is set as ToUint32('name') + 1
+# if ToUint32('name') is greater than value of the length property in 'O'
+# (15.4.5.1 step 4.e.ii)
+15.2.3.6-4-276: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is own property which is defined in both
+# [[ParameterMap]] of 'O' and 'O', and is deleted afterwards, and 'desc' is
+# data descriptor, test 'name' is redefined in 'O' with all correct
+# attribute values (10.6 [[DefineOwnProperty]] step 3)
+15.2.3.6-4-289-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is own property which is defined in both
+# [[ParameterMap]] of 'O' and 'O', is deleted afterwards, and 'desc' is
+# accessor descriptor, test 'name' is redefined in 'O' with all correct
+# attribute values (10.6 [[DefineOwnProperty]] step 3)
+15.2.3.6-4-290-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is own accessor property of 'O' which is also
+# defined in [[ParameterMap]] of 'O', and 'desc' is accessor descriptor,
+# test updating multiple attribute values of 'name' (10.6
+# [[DefineOwnProperty]] step 3 and 5.a.i)
+15.2.3.6-4-291-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object, 'name' is own
+# accessor property of 'O', and 'desc' is accessor descriptor, test
+# updating multiple attribute values of 'name' (10.6 [[DefineOwnProperty]]
+# step 3)
+15.2.3.6-4-291: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is own data property of 'O' which is also
+# defined in [[ParameterMap]] of 'O', test TypeError is not thrown when
+# updating the [[Value]] attribute value of 'name' which is defined as
+# non-writable and configurable (10.6 [[DefineOwnProperty]] step 3 and step
+# 5.b)
+15.2.3.6-4-293-3: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is own accessor property of 'O' which is also
+# defined in [[ParameterMap]] of 'O', test TypeError is thrown when
+# updating the [[Get]] attribute value of 'name' which is defined as
+# non-configurable (10.6 [[DefineOwnProperty]] step 4 and step 5a)
+15.2.3.6-4-297-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is own accessor property of 'O' which is also
+# defined in [[ParameterMap]] of 'O', test TypeError is thrown when
+# updating the [[Set]] attribute value of 'name' which is defined as
+# non-configurable (10.6 [[DefineOwnProperty]] steps 4 and 5a)
+15.2.3.6-4-298-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is own accessor property of 'O' which is also
+# defined in [[ParameterMap]] of 'O', test TypeError is thrown when
+# updating the [[Enumerable]] attribute value of 'name' which is defined as
+# non-configurable (10.6 [[DefineOwnProperty]] steps 4 and 5a)
+15.2.3.6-4-299-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is an index named property of 'O', and 'desc'
+# is data descriptor, test 'name' is defined in 'O' with all correct
+# attribute values (10.6 [[DefineOwnProperty]] step 3)
+15.2.3.6-4-301-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
+# formal parameters, 'name' is an index named property of 'O' but not
+# defined in [[ParameterMap]] of 'O', and 'desc' is accessor descriptor,
+# test 'name' is defined in 'O' with all correct attribute values (10.6
+# [[DefineOwnProperty]] step 3 and step 5a)
+15.2.3.6-4-302-1: FAIL
+# Bug? Object.defineProperty - 'O' is an Arguments object, 'name' is an index
+# named accessor property of 'O' but not defined in [[ParameterMap]] of
+# 'O', and 'desc' is accessor descriptor, test updating multiple attribute
+# values of 'name' (10.6 [[DefineOwnProperty]] step 3)
+15.2.3.6-4-303: FAIL
+# Bug? ES5 Attributes - [[Value]] attribute of data property is the activex host
+# object
+15.2.3.6-4-401: FAIL
+# Bug? ES5 Attributes - Failed to add a property to an object when the object's
+# object has a property with same name and [[Writable]] attribute is set to
+# false (Number instance)
+15.2.3.6-4-405: FAIL
+# Bug? ES5 Attributes - Failed to add a property to an object when the object's
+# prototype has a property with the same name and [[Writable]] set to false
+# (JSON)
+15.2.3.6-4-410: FAIL
+# Bug? ES5 Attributes - Failed to add properties to an object when the object's
+# prototype has properties with the same name and [[Writable]] set to false
+# (Object.create)
+15.2.3.6-4-415: FAIL
+# Bug? ES5 Attributes - Failed to add a property to an object when the object's
+# prototype has a property with the same name and [[Writable]] set to
+# false(Function.prototype.bind)
+15.2.3.6-4-420: FAIL
+# Bug? ES5 Attributes - Fail to add property into object (Number instance)
+15.2.3.6-4-581: FAIL
+# Bug? ES5 Attributes - Fail to update value of property into of [[Proptotype]]
+# internal property (JSON)
+15.2.3.6-4-586: FAIL
+# Bug? ES5 Attributes - Fail to update value of property of [[Proptotype]]
+# internal property (Object.create)
+15.2.3.6-4-591: FAIL
+# Bug? ES5 Attributes - Fail to update value of property into of [[Proptotype]]
+# internal property (Function.prototype.bind)
+15.2.3.6-4-596: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.indexOf are correct
+15.2.3.6-4-612: FAIL
+# Bug? ES5 Attributes - all attributes in Object.lastIndexOf are correct
+15.2.3.6-4-613: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.every are correct
+15.2.3.6-4-614: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.some are correct
+15.2.3.6-4-615: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.forEach are correct
+15.2.3.6-4-616: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.map are correct
+15.2.3.6-4-617: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.filter are correct
+15.2.3.6-4-618: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.reduce are correct
+15.2.3.6-4-619: FAIL
+# Bug? ES5 Attributes - all attributes in Array.prototype.reduceRight are
+# correct
+15.2.3.6-4-620: FAIL
+# Bug? ES5 Attributes - all attributes in String.prototype.trim are correct
+15.2.3.6-4-621: FAIL
+# Bug? ES5 Attributes - all attributes in Date.prototype.toISOString are correct
+15.2.3.6-4-623: FAIL
+# Bug? ES5 Attributes - all attributes in Date.prototype.toJSON are correct
+15.2.3.6-4-624: FAIL
+# Bug? Object.defineProperties - argument 'Properties' is an Error object
+# props.description = obj1;
+15.2.3.7-2-15: FAIL
+# Bug? Object.defineProperties - 'Properties' is an Error object which
+# implements its own [[Get]] method to get enumerable own property
+# props.description = obj1;
+15.2.3.7-5-a-16: FAIL
+# Bug? Object.defineProperties - 'set' property of 'descObj' is not present
+# (8.10.5 step 8)
+15.2.3.7-5-b-227: FAIL
+# Bug? Object.defineProperties - 'descObj' is an Error object which implements
+# its own [[Get]] method to get 'set' property (8.10.5 step 8.a)
+# descObj.description = { value: 11 };
+15.2.3.7-5-b-248: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, test the length property of
+# 'O' is own data property (15.4.5.1 step 1)
+15.2.3.7-6-a-112: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, test the length property of
+# 'O' is own data property that overrides an inherited data property
+# (15.4.5.1 step 1)
+15.2.3.7-6-a-113: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', test RangeError is thrown when setting the [[Value]] field of 'desc'
+# to undefined (15.4.5.1 step 3.c)
+15.2.3.7-6-a-121: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', test setting the [[Value]] field of 'desc' to null actuall is set to
+# 0 (15.4.5.1 step 3.c)
+15.2.3.7-6-a-122: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a boolean with value false
+# (15.4.5.1 step 3.c)
+15.2.3.7-6-a-123: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a boolean with value true
+# (15.4.5.1 step 3.c)
+15.2.3.7-6-a-124: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is 0 (15.4.5.1 step 3.c)
+15.2.3.7-6-a-125: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is +0 (15.4.5.1 step 3.c)
+15.2.3.7-6-a-126: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is -0 (15.4.5.1 step 3.c)
+15.2.3.7-6-a-127: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is positive number (15.4.5.1
+# step 3.c)
+15.2.3.7-6-a-128: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is negative number (15.4.5.1
+# step 3.c)
+15.2.3.7-6-a-129: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is +Infinity (15.4.5.1 step
+# 3.c)
+15.2.3.7-6-a-130: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is -Infinity (15.4.5.1 step
+# 3.c)
+15.2.3.7-6-a-131: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is NaN (15.4.5.1 step 3.c)
+15.2.3.7-6-a-132: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing a
+# positive number (15.4.5.1 step 3.c)
+15.2.3.7-6-a-133: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing a
+# negative number (15.4.5.1 step 3.c)
+15.2.3.7-6-a-134: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing a
+# decimal number (15.4.5.1 step 3.c)
+15.2.3.7-6-a-135: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing
+# +Infinity (15.4.5.1 step 3.c)
+15.2.3.7-6-a-136: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing
+# -Infinity (15.4.5.1 step 3.c)
+15.2.3.7-6-a-137: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing an
+# exponential number (15.4.5.1 step 3.c)
+15.2.3.7-6-a-138: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing an hex
+# number (15.4.5.1 step 3.c)
+15.2.3.7-6-a-139: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is a string containing an
+# leading zero number (15.4.5.1 step 3.c)
+15.2.3.7-6-a-140: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', test the [[Value]] field of 'desc' is a string which doesn't convert
+# to a number (15.4.5.1 step 3.c)
+15.2.3.7-6-a-141: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', test the [[Value]] field of 'desc' is an Object which has an own
+# toString method (15.4.5.1 step 3.c)
+15.2.3.7-6-a-142: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is an Object which has an own
+# valueOf method (15.4.5.1 step 3.c)
+15.2.3.7-6-a-143: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is an Object which has an own
+# valueOf method that returns an object and toString method that returns a
+# string (15.4.5.1 step 3.c)
+15.2.3.7-6-a-144: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is an Object which has an own
+# toString and valueOf method (15.4.5.1 step 3.c)
+15.2.3.7-6-a-145: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test TypeError is thrown when the [[Value]] field of 'desc' is an
+# Object that both toString and valueOf wouldn't return primitive value
+# (15.4.5.1 step 3.c)
+15.2.3.7-6-a-146: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test using inherited valueOf method when the [[Value]] field of
+# 'desc' is an Objec with an own toString and inherited valueOf methods
+# (15.4.5.1 step 3.c)
+15.2.3.7-6-a-147: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
+# positive non-integer values (15.4.5.1 step 3.c)
+15.2.3.7-6-a-148: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
+# negative non-integer values (15.4.5.1 step 3.c)
+15.2.3.7-6-a-149: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 2
+# (15.4.5.1 step 3.c)
+15.2.3.7-6-a-150: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 1
+# (15.4.5.1 step 3.c)
+15.2.3.7-6-a-151: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
+# boundary value 2^32 (15.4.5.1 step 3.c)
+15.2.3.7-6-a-152: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
+# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
+# boundary value 2^32 + 1 (15.4.5.1 step 3.c)
+15.2.3.7-6-a-153: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', test the [[Value]] field of 'desc' which is greater than value of
+# the length property is defined into 'O' without deleting any property
+# with large index named (15.4.5.1 step 3.f)
+15.2.3.7-6-a-155: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', test the [[Value]] field of 'desc' which is less than value of the
+# length property is defined into 'O' with deleting properties with large
+# index named (15.4.5.1 step 3.f)
+15.2.3.7-6-a-157: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to true at last after deleting properties with large index named if the
+# [[Writable]] field of 'desc' is absent (15.4.5.1 step 3.h)
+15.2.3.7-6-a-161: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to true at last after deleting properties with large index named if the
+# [[Writable]] field of 'desc' is true (15.4.5.1 step 3.h)
+15.2.3.7-6-a-162: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to false at last after deleting properties with large index named if the
+# [[Writable]] field of 'desc' is false (15.4.5.1 step 3.i.ii)
+15.2.3.7-6-a-163: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property in 'O'
+# is set as true before deleting properties with large index named
+# (15.4.5.1 step 3.i.iii)
+15.2.3.7-6-a-164: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the length property is decreased by 1 (15.4.5.1 step
+# 3.l.i)
+15.2.3.7-6-a-165: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own data property with
+# large index named in 'O' can stop deleting index named properties
+# (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-166: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of inherited data property
+# with large index named in 'O' can't stop deleting index named properties
+# (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-167: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own data property with
+# large index named in 'O' that overrides inherited data property can stop
+# deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-168: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own data property with
+# large index named in 'O' that overrides inherited accessor property can
+# stop deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-169: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own accessor property
+# with large index named in 'O' can stop deleting index named properties
+# (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-170: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of inherited accessor
+# property with large index named in 'O' can't stop deleting index named
+# properties (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-171: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own accessor property
+# with large index named in 'O' that overrides inherited data property can
+# stop deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-172: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Configurable]] attribute of own accessor property
+# with large index named in 'O' that overrides inherited accessor property
+# can stop deleting index named properties (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-173: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the configurable large index named property of 'O' can be
+# deleted (15.4.5.1 step 3.l.ii)
+15.2.3.7-6-a-174: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test value of the length property is set to the last
+# non-configurable index named property of 'O' plus 1 (15.4.5.1 step
+# 3.l.iii.1)
+15.2.3.7-6-a-175: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to false at last when the [[Writable]] field of 'desc' is false and 'O'
+# contains non-configurable large index named property (15.4.5.1 step
+# 3.l.iii.2)
+15.2.3.7-6-a-176: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
+# 'O', the [[Value]] field of 'desc' is less than value of the length
+# property, test the [[Writable]] attribute of the length property is set
+# to false at last when the [[Writable]] field of 'desc' is false and 'O'
+# doesn't contain non-configurable large index named property (15.4.5.1
+# step 3.m)
+15.2.3.7-6-a-177: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
+# property, 'P' is boundary value 2^32 - 2 (15.4.5.1 step 4.a)
+15.2.3.7-6-a-179: FAIL
+# Bug? Object.defineProperties - TypeError is thrown if 'O' is an Array, 'P' is
+# an array index named property,[[Writable]] attribute of the length
+# property in 'O' is false, value of 'P' is equal to value of the length
+# property in 'O' (15.4.5.1 step 4.b)
+15.2.3.7-6-a-184: FAIL
+# Bug? Object.defineProperties - TypeError is thrown if 'O' is an Array, 'P' is
+# an array index named property,[[Writable]] attribute of the length
+# property in 'O' is false, value of 'P' is bigger than value of the length
+# property in 'O' (15.4.5.1 step 4.b)
+15.2.3.7-6-a-185: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
+# property, 'desc' is accessor descriptor, test updating all attribute
+# values of 'P' (15.4.5.1 step 4.c)
+15.2.3.7-6-a-205: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
+# property that already exists on 'O' is accessor property and 'desc' is
+# accessor descriptor, test updating the [[Enumerable]] attribute value of
+# 'P' (15.4.5.1 step 4.c)
+15.2.3.7-6-a-260: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
+# property that already exists on 'O' is accessor property and 'desc' is
+# accessor descriptor, test updating the [[Configurable]] attribute value
+# of 'P' (15.4.5.1 step 4.c)
+15.2.3.7-6-a-261: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
+# property that already exists on 'O' is accessor property and 'desc' is
+# accessor descriptor, test updating multiple attribute values of 'P'
+# (15.4.5.1 step 4.c)
+15.2.3.7-6-a-262: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
+# property, test the length property of 'O' is set as ToUint32('P') + 1 if
+# ToUint32('P') equals to value of the length property in 'O' (15.4.5.1
+# step 4.e.ii)
+15.2.3.7-6-a-264: FAIL
+# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
+# property, test the length property of 'O' is set as ToUint32('P') + 1 if
+# ToUint32('P') is greater than value of the length property in 'O'
+# (15.4.5.1 step 4.e.ii)
+15.2.3.7-6-a-265: FAIL
+# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own accessor
+# property of 'O' which is also defined in [[ParameterMap]] of 'O', and
+# 'desc' is accessor descriptor, test updating multiple attribute values of
+# 'P' (10.6 [[DefineOwnProperty]] step 3)
+15.2.3.7-6-a-280: FAIL
+# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is an array
+# index named accessor property of 'O' but not defined in [[ParameterMap]]
+# of 'O', and 'desc' is accessor descriptor, test updating multiple
+# attribute values of 'P' (10.6 [[DefineOwnProperty]] step 3)
+15.2.3.7-6-a-292: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into the
+# returned object
+15.2.3.10-3-2: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into a
+# Function object
+15.2.3.10-3-3: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into an
+# Array object
+15.2.3.10-3-4: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into a
+# String object
+15.2.3.10-3-5-1: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into a
+# Boolean object
+15.2.3.10-3-6: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into a
+# Number object
+15.2.3.10-3-7: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into a Date
+# object
+15.2.3.10-3-8: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into a
+# RegExp object
+15.2.3.10-3-9: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into an
+# Error object
+15.2.3.10-3-10: FAIL
+# Bug? Object.preventExtensions - indexed properties cannot be added into an
+# Arguments object
+15.2.3.10-3-11: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into the
+# returned object
+15.2.3.10-3-12: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into a
+# Function object
+15.2.3.10-3-13: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into an Array
+# object
+15.2.3.10-3-14: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into a String
+# object
+15.2.3.10-3-15: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into a
+# Boolean object
+15.2.3.10-3-16: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into a Number
+# object
+15.2.3.10-3-17: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into a Date
+# object
+15.2.3.10-3-18: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into a RegExp
+# object
+15.2.3.10-3-19: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into an Error
+# object
+15.2.3.10-3-20: FAIL
+# Bug? Object.preventExtensions - named properties cannot be added into an
+# Arguments object
+15.2.3.10-3-21: FAIL
+# Bug? Object.prototype.toString - '[object Undefined]' will be returned when
+# 'this' value is undefined
+15.2.4.2-1-1: FAIL
+# Bug? Object.prototype.toString - '[object Undefined]' will be returned when
+# 'this' value is undefined
+15.2.4.2-1-2: FAIL
+# Bug? Object.prototype.toString - '[object Null]' will be returned when 'this'
+# value is null
+15.2.4.2-2-1: FAIL
+# Bug? Object.prototype.toString - '[object Null]' will be returned when 'this'
+# value is null
+15.2.4.2-2-2: FAIL
+# Bug? Function.prototype.bind - [[Get]] attribute of 'caller' property in 'F'
+# is thrower
+15.3.4.5-20-2: FAIL
+# Bug? Function.prototype.bind - [[Set]] attribute of 'caller' property in 'F'
+# is thrower
+15.3.4.5-20-3: FAIL
+# Bug? Function.prototype.bind - [[Get]] attribute of 'arguments' property in
+# 'F' is thrower
+15.3.4.5-21-2: FAIL
+# Bug? Function.prototype.bind - [[Set]] attribute of 'arguments' property in
+# 'F' is thrower
+15.3.4.5-21-3: FAIL
+# Bug? Array.prototype.concat will concat an Array when index property
+# (read-only) exists in Array.prototype (Step 5.c.i)
+15.4.4.4-5-c-i-1: FAIL
+# Bug? Array.prototype.indexOf applied to undefined throws a TypeError
+15.4.4.14-1-1: FAIL
+# Bug? Array.prototype.indexOf applied to null throws a TypeError
+15.4.4.14-1-2: FAIL
+# Bug? Array.prototype.indexOf - side effects produced by step 1 are visible
+# when an exception occurs
+15.4.4.14-5-28: FAIL
+# Bug? Array.prototype.indexOf - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.14-9-a-19: FAIL
+# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
+# property that overrides an inherited data property on an Array
+15.4.4.14-9-b-i-11: FAIL
+# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
+# property that overrides an inherited accessor property on an Array
+15.4.4.14-9-b-i-13: FAIL
+# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
+# property without a get function on an Array
+15.4.4.14-9-b-i-17: FAIL
+# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
+# property without a get function that overrides an inherited accessor
+# property on an Array
+15.4.4.14-9-b-i-19: FAIL
+# Bug? Array.prototype.indexOf - side-effects are visible in subsequent
+# iterations on an Array
+15.4.4.14-9-b-i-28: FAIL
+# Bug? Array.prototype.indexOf - terminates iteration on unhandled exception on
+# an Array
+15.4.4.14-9-b-i-30: FAIL
+# Bug? Array.prototype.lastIndexOf applied to undefined throws a TypeError
+15.4.4.15-1-1: FAIL
+# Bug? Array.prototype.lastIndexOf applied to null throws a TypeError
+15.4.4.15-1-2: FAIL
+# Bug? Array.prototype.lastIndexOf - side effects produced by step 1 are visible
+# when an exception occurs
+15.4.4.15-5-28: FAIL
+# Bug? Array.prototype.lastIndexOf - deleting property of prototype causes
+# prototype index property not to be visited on an Array
+15.4.4.15-8-a-14: FAIL
+# Bug? Array.prototype.lastIndexOf - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.15-8-a-19: FAIL
+# Bug? Array.prototype.lastIndexOf - element to be retrieved is own accessor
+# property that overrides an inherited data property on an Array
+15.4.4.15-8-b-i-11: FAIL
+# Bug? Array.prototype.lastIndexOf - element to be retrieved is own accessor
+# property that overrides an inherited accessor property on an Array
+15.4.4.15-8-b-i-13: FAIL
+# Bug? Array.prototype.lastIndexOf - element to be retrieved is own accessor
+# property without a get function on an Array
+15.4.4.15-8-b-i-17: FAIL
+# Bug? Array.prototype.lastIndexOf - side-effects are visible in subsequent
+# iterations on an Array
+15.4.4.15-8-b-i-28: FAIL
+# Bug? Array.prototype.lastIndexOf terminates iteration on unhandled exception
+# on an Array
+15.4.4.15-8-b-i-30: FAIL
+# Bug? Array.prototype.every - side effects produced by step 2 are visible when
+# an exception occurs
+15.4.4.16-4-8: FAIL
+# Bug? Array.prototype.every - side effects produced by step 3 are visible when
+# an exception occurs
+15.4.4.16-4-9: FAIL
+# Bug? Array.prototype.every - the exception is not thrown if exception was
+# thrown by step 2
+15.4.4.16-4-10: FAIL
+# Bug? Array.prototype.every - the exception is not thrown if exception was
+# thrown by step 3
+15.4.4.16-4-11: FAIL
+# Bug? Array.prototype.every - calling with no callbackfn is the same as passing
+# undefined for callbackfn
+15.4.4.16-4-15: FAIL
+# Bug? Array.prototype.every - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.16-7-b-16: FAIL
+# Bug? Array.prototype.every - element to be retrieved is own accessor property
+# on an Array
+15.4.4.16-7-c-i-10: FAIL
+# Bug? Array.prototype.every - element to be retrieved is own accessor property
+# that overrides an inherited data property on an Array
+15.4.4.16-7-c-i-12: FAIL
+# Bug? Array.prototype.every - element to be retrieved is own accessor property
+# that overrides an inherited accessor property on an Array
+15.4.4.16-7-c-i-14: FAIL
+# Bug? Array.prototype.every - element to be retrieved is own accessor property
+# without a get function on an Array
+15.4.4.16-7-c-i-18: FAIL
+# Bug? Array.prototype.every - element to be retrieved is own accessor property
+# without a get function that overrides an inherited accessor property on
+# an Array
+15.4.4.16-7-c-i-20: FAIL
+# Bug? Array.prototype.every - element changed by getter on previous iterations
+# is observed on an Array
+15.4.4.16-7-c-i-28: FAIL
+# Bug? Array.prototype.some - side effects produced by step 2 are visible when
+# an exception occurs
+15.4.4.17-4-8: FAIL
+# Bug? Array.prototype.some - side effects produced by step 3 are visible when
+# an exception occurs
+15.4.4.17-4-9: FAIL
+# Bug? Array.prototype.some - the exception is not thrown if exception was
+# thrown by step 2
+15.4.4.17-4-10: FAIL
+# Bug? Array.prototype.some - the exception is not thrown if exception was
+# thrown by step 3
+15.4.4.17-4-11: FAIL
+# Bug? Array.prototype.some - calling with no callbackfn is the same as passing
+# undefined for callbackfn
+15.4.4.17-4-15: FAIL
+# Bug? Array.prototype.some - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.17-7-b-16: FAIL
+# Bug? Array.prototype.some - element to be retrieved is own accessor property
+# on an Array
+15.4.4.17-7-c-i-10: FAIL
+# Bug? Array.prototype.some - element to be retrieved is own accessor property
+# that overrides an inherited data property on an Array
+15.4.4.17-7-c-i-12: FAIL
+# Bug? Array.prototype.some - element to be retrieved is own accessor property
+# that overrides an inherited accessor property on an Array
+15.4.4.17-7-c-i-14: FAIL
+# Bug? Array.prototype.some - element to be retrieved is own accessor property
+# without a get function on an Array
+15.4.4.17-7-c-i-18: FAIL
+# Bug? Array.prototype.some - element to be retrieved is own accessor property
+# without a get function that overrides an inherited accessor property on
+# an Array
+15.4.4.17-7-c-i-20: FAIL
+# Bug? Array.prototype.some - element changed by getter on previous iterations
+# is observed on an Array
+15.4.4.17-7-c-i-28: FAIL
+# Bug? Array.prototype.forEach - side effects produced by step 2 are visible
+# when an exception occurs
+15.4.4.18-4-8: FAIL
+# Bug? Array.prototype.forEach - side effects produced by step 3 are visible
+# when an exception occurs
+15.4.4.18-4-9: FAIL
+# Bug? Array.prototype.forEach - the exception is not thrown if exception was
+# thrown by step 2
+15.4.4.18-4-10: FAIL
+# Bug? Array.prototype.forEach - the exception is not thrown if exception was
+# thrown by step 3
+15.4.4.18-4-11: FAIL
+# Bug? Array.prototype.forEach - calling with no callbackfn is the same as
+# passing undefined for callbackfn
+15.4.4.18-4-15: FAIL
+# Bug? Array.prototype.forEach - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.18-7-b-16: FAIL
+# Bug? Array.prototype.forEach - element to be retrieved is own accessor
+# property on an Array
+15.4.4.18-7-c-i-10: FAIL
+# Bug? Array.prototype.forEach - element to be retrieved is own accessor
+# property that overrides an inherited data property on an Array
+15.4.4.18-7-c-i-12: FAIL
+# Bug? Array.prototype.forEach - element to be retrieved is own accessor
+# property that overrides an inherited accessor property on an Array
+15.4.4.18-7-c-i-14: FAIL
+# Bug? Array.prototype.forEach - element to be retrieved is own accessor
+# property without a get function on an Array
+15.4.4.18-7-c-i-18: FAIL
+# Bug? Array.prototype.forEach - element to be retrieved is own accessor
+# property without a get function that overrides an inherited accessor
+# property on an Array
+15.4.4.18-7-c-i-20: FAIL
+# Bug? Array.prototype.forEach - element changed by getter on previous
+# iterations is observed on an Array
+15.4.4.18-7-c-i-28: FAIL
+# Bug? Array.prototype.map - applied to Array-like object, 'length' is an own
+# data property that overrides an inherited accessor property
+15.4.4.19-2-5: FAIL
+# Bug? Array.prototype.map - Side effects produced by step 2 are visible when an
+# exception occurs
+15.4.4.19-4-8: FAIL
+# Bug? Array.prototype.map - Side effects produced by step 3 are visible when an
+# exception occurs
+15.4.4.19-4-9: FAIL
+# Bug? Array.prototype.map - the exception is not thrown if exception was thrown
+# by step 2
+15.4.4.19-4-10: FAIL
+# Bug? Array.prototype.map - the exception is not thrown if exception was thrown
+# by step 3
+15.4.4.19-4-11: FAIL
+# Bug? Array.prototype.map - calling with no callbackfn is the same as passing
+# undefined for callbackfn
+15.4.4.19-4-15: FAIL
+# Bug? Array.prototype.map - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.19-8-b-16: FAIL
+# Bug? Array.prototype.map - element to be retrieved is own accessor property on
+# an Array
+15.4.4.19-8-c-i-10: FAIL
+# Bug? Array.prototype.map - element to be retrieved is own accessor property
+# that overrides an inherited data property on an Array
+15.4.4.19-8-c-i-12: FAIL
+# Bug? Array.prototype.map - element to be retrieved is own accessor property
+# that overrides an inherited accessor property on an Array
+15.4.4.19-8-c-i-14: FAIL
+# Bug? Array.prototype.map - element to be retrieved is own accessor property
+# without a get function on an Array
+15.4.4.19-8-c-i-18: FAIL
+# Bug? Array.prototype.map - element to be retrieved is own accessor property
+# without a get function that overrides an inherited accessor property on
+# an Array
+15.4.4.19-8-c-i-19: FAIL
+# Bug? Array.prototype.map - element changed by getter on previous iterations is
+# observed on an Array
+15.4.4.19-8-c-i-28: FAIL
+# Bug? Array.prototype.filter - value of 'length' is a number (value is
+# negative)
+15.4.4.20-3-7: FAIL
+# Bug? Array.prototype.filter - value of 'length' is a number (value is
+# Infinity)
+# V8 timeout
+15.4.4.20-3-8: SKIP
+# Bug? Array.prototype.filter - 'length' is a string containing a negative
+# number
+15.4.4.20-3-12: FAIL
+# Bug? Array.prototype.filter - 'length' is a string containing a decimal number
+15.4.4.20-3-13: FAIL
+# Bug? Array.prototype.filter - 'length' is a string containing +/-Infinity
+15.4.4.20-3-14: SKIP
+# Bug? Array.prototype.filter - value of 'length' is a positive non-integer,
+# ensure truncation occurs in the proper direction
+# V8 timeout
+15.4.4.20-3-24: FAIL
+# Bug? Array.prototype.filter - value of 'length' is a negative non-integer,
+# ensure truncation occurs in the proper direction
+15.4.4.20-3-25: FAIL
+# Bug? Array.prototype.filter - value of 'length' is boundary value (2^32)
+# V8 timeout
+15.4.4.20-3-28: SKIP
+# Bug? Array.prototype.filter - value of 'length' is boundary value (2^32 + 1)
+# V8 timeout
+15.4.4.20-3-29: SKIP
+# Bug? Array.prototype.filter - side effects produced by step 2 are visible when
+# an exception occurs
+15.4.4.20-4-8: FAIL
+# Bug? Array.prototype.filter - side effects produced by step 3 are visible when
+# an exception occurs
+15.4.4.20-4-9: FAIL
+# Bug? Array.prototype.filter - the exception is not thrown if exception was
+# thrown by step 2
+15.4.4.20-4-10: FAIL
+# Bug? Array.prototype.filter - the exception is not thrown if exception was
+# thrown by step 3
+15.4.4.20-4-11: FAIL
+# Bug? Array.prototype.filter - calling with no callbackfn is the same as
+# passing undefined for callbackfn
+15.4.4.20-4-15: FAIL
+# Bug? Array.prototype.filter - properties can be added to prototype after
+# current position are visited on an Array-like object
+15.4.4.20-9-b-6: FAIL
+# Bug? Array.prototype.filter - properties can be added to prototype after
+# current position are visited on an Array
+15.4.4.20-9-b-7: FAIL
+# Bug? Array.prototype.filter - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.20-9-b-16: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is own data property
+# that overrides an inherited accessor property on an Array
+15.4.4.20-9-c-i-6: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is own accessor property
+# on an Array
+15.4.4.20-9-c-i-10: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is own accessor property
+# that overrides an inherited data property on an Array
+15.4.4.20-9-c-i-12: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is own accessor property
+# that overrides an inherited accessor property on an Array
+15.4.4.20-9-c-i-14: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is inherited accessor
+# property on an Array
+15.4.4.20-9-c-i-16: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is own accessor property
+# without a get function on an Array
+15.4.4.20-9-c-i-18: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is own accessor property
+# without a get function that overrides an inherited accessor property on
+# an Array
+15.4.4.20-9-c-i-20: FAIL
+# Bug? Array.prototype.filter - element to be retrieved is inherited accessor
+# property without a get function on an Array
+15.4.4.20-9-c-i-22: FAIL
+# Bug? Array.prototype.filter - element changed by getter on previous iterations
+# is observed on an Array
+15.4.4.20-9-c-i-28: FAIL
+# Bug? Array.prototype.reduce - value of 'length' is a number (value is
+# negative)
+15.4.4.21-3-7: FAIL
+# Bug? Array.prototype.reduce - value of 'length' is a number (value is
+# Infinity)
+# V8 timeout.
+15.4.4.21-3-8: SKIP
+# Bug? Array.prototype.reduce - 'length' is a string containing a negative
+# number
+15.4.4.21-3-12: FAIL
+# Bug? Array.prototype.reduce - 'length' is a string containing a decimal number
+15.4.4.21-3-13: FAIL
+# Bug? Array.prototype.reduce - 'length' is a string containing +/-Infinity
+# V8 timeout.
+15.4.4.21-3-14: SKIP
+# Bug? Array.prototype.reduce - value of 'length' is a positive non-integer,
+# ensure truncation occurs in the proper direction
+15.4.4.21-3-24: FAIL
+# Bug? Array.prototype.reduce - value of 'length' is a negative non-integer,
+# ensure truncation occurs in the proper direction
+15.4.4.21-3-25: FAIL
+# Bug? Array.prototype.reduce - value of 'length' is boundary value (2^32)
+# V8 timeout.
+15.4.4.21-3-28: SKIP
+# Bug? Array.prototype.reduce - value of 'length' is boundary value (2^32 + 1)
+# V8 timeout.
+15.4.4.21-3-29: SKIP
+# Bug? Array.prototype.reduce - side effects produced by step 2 are visible when
+# an exception occurs
+15.4.4.21-4-8: FAIL
+# Bug? Array.prototype.reduce - side effects produced by step 3 are visible when
+# an exception occurs
+15.4.4.21-4-9: FAIL
+# Bug? Array.prototype.reduce - the exception is not thrown if exception was
+# thrown by step 2
+15.4.4.21-4-10: FAIL
+# Bug? Array.prototype.reduce - the exception is not thrown if exception was
+# thrown by step 3
+15.4.4.21-4-11: FAIL
+# Bug? Array.prototype.reduce - calling with no callbackfn is the same as
+# passing undefined for callbackfn
+15.4.4.21-4-15: FAIL
+# Bug? Array.prototype.reduce - decreasing length of array in step 8 does not
+# delete non-configurable properties
+15.4.4.21-9-b-16: FAIL
+# Bug? Array.prototype.reduce - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.21-9-b-29: FAIL
+# Bug? Array.prototype.reduceRight - value of 'length' is a number (value is
+# negative)
+15.4.4.22-3-7: FAIL
+# Bug? Array.prototype.reduceRight - value of 'length' is a number (value is
+# Infinity)
+# V8 timeout.
+15.4.4.22-3-8: SKIP
+# Bug? Array.prototype.reduceRight - value of 'length' is a string containing a
+# negative number
+15.4.4.22-3-12: FAIL
+# Bug? Array.prototype.reduceRight - value of 'length' is a string containing a
+# decimal number
+15.4.4.22-3-13: FAIL
+# Bug? Array.prototype.reduceRight - value of 'length' is a string containing
+# +/-Infinity
+# V8 timeout.
+15.4.4.22-3-14: SKIP
+# Bug? Array.prototype.reduceRight - value of 'length' is a positive
+# non-integer, ensure truncation occurs in the proper direction
+15.4.4.22-3-24: FAIL
+# Bug? Array.prototype.reduceRight - value of 'length' is a negative
+# non-integer, ensure truncation occurs in the proper direction
+15.4.4.22-3-25: FAIL
+# Bug? Array.prototype.reduceRight - value of 'length' is boundary value (2^32)
+# V8 timeout.
+15.4.4.22-3-28: SKIP
+# Bug? Array.prototype.reduceRight - value of 'length' is boundary value (2^32 +
+# 1)
+# V8 timeout.
+15.4.4.22-3-29: SKIP
+# Bug? Array.prototype.reduceRight - side effects produced by step 2 are visible
+# when an exception occurs
+15.4.4.22-4-8: FAIL
+# Bug? Array.prototype.reduceRight - side effects produced by step 3 are visible
+# when an exception occurs
+15.4.4.22-4-9: FAIL
+# Bug? Array.prototype.reduceRight - the exception is not thrown if exception
+# was thrown by step 2
+15.4.4.22-4-10: FAIL
+# Bug? Array.prototype.reduceRight - the exception is not thrown if exception
+# was thrown by step 3
+15.4.4.22-4-11: FAIL
+# Bug? Array.prototype.reduceRight - calling with no callbackfn is the same as
+# passing undefined for callbackfn
+15.4.4.22-4-15: FAIL
+# Bug? Array.prototype.reduceRight - element to be retrieved is own accessor
+# property that overrides an inherited data property on an Array
+15.4.4.22-8-b-iii-1-12: FAIL
+# Bug? Array.prototype.reduceRight - element to be retrieved is own accessor
+# property without a get function on an Array
+15.4.4.22-8-b-iii-1-18: FAIL
+# Bug? Array.prototype.reduceRight - element to be retrieved is own accessor
+# property without a get function that overrides an inherited accessor
+# property on an Array
+15.4.4.22-8-b-iii-1-20: FAIL
+# Bug? Array.prototype.reduceRight - element changed by getter on current
+# iteration is observed in subsequent iterations on an Array
+15.4.4.22-8-b-iii-1-30: FAIL
+# Bug? Array.prototype.reduceRight - Exception in getter terminate iteration on
+# an Array
+15.4.4.22-8-b-iii-1-33: FAIL
+# Bug? Array.prototype.reduceRight - modifications to length don't change number
+# of iterations in step 9
+15.4.4.22-8-b-2: FAIL
+# Bug? Array.prototype.reduceRight - deleting own property in step 8 causes
+# deleted index property not to be visited on an Array
+15.4.4.22-9-b-9: FAIL
+# Bug? Array.prototype.reduceRight - deleting own property with prototype
+# property in step 8 causes prototype index property to be visited on an
+# Array
+15.4.4.22-9-b-13: FAIL
+# Bug? Array.prototype.reduceRight - decreasing length of array in step 8 does
+# not delete non-configurable properties
+15.4.4.22-9-b-16: FAIL
+# Bug? Array.prototype.reduceRight - deleting property of prototype causes
+# deleted index property not to be visited on an Array
+15.4.4.22-9-b-24: FAIL
+# Bug? Array.prototype.reduceRight - deleting own property with prototype
+# property causes prototype index property to be visited on an Array
+15.4.4.22-9-b-26: FAIL
+# Bug? Array.prototype.reduceRight - decreasing length of array does not delete
+# non-configurable properties
+15.4.4.22-9-b-29: FAIL
+# Bug? Array.prototype.reduceRight - element changed by getter on previous
+# iterations is observed on an Array
+15.4.4.22-9-c-i-30: FAIL
+# Bug? Array.prototype.reduceRight - modifications to length will change number
+# of iterations
+15.4.4.22-9-9: FAIL
+# Bug? String.prototype.trim throws TypeError when string is undefined
+15.5.4.20-1-1: FAIL
+# Bug? String.prototype.trim throws TypeError when string is null
+15.5.4.20-1-2: FAIL
+# Bug? String.prototype.trim - 'S' is a string with all WhiteSpace
+15.5.4.20-3-2: FAIL
+# Bug? String.prototype.trim - 'S' is a string with all union of WhiteSpace and
+# LineTerminator
+15.5.4.20-3-3: FAIL
+# Bug? String.prototype.trim - 'S' is a string start with union of all
+# LineTerminator and all WhiteSpace
+15.5.4.20-3-4: FAIL
+# Bug? String.prototype.trim - 'S' is a string end with union of all
+# LineTerminator and all WhiteSpace
+15.5.4.20-3-5: FAIL
+# Bug? String.prototype.trim - 'S' is a string start with union of all
+# LineTerminator and all WhiteSpace and end with union of all
+# LineTerminator and all WhiteSpace
+15.5.4.20-3-6: FAIL
+# Bug? String.prototype.trim handles whitepace and lineterminators (\\uFEFFabc)
+15.5.4.20-4-10: FAIL
+# Bug? String.prototype.trim handles whitepace and lineterminators (abc\\uFEFF)
+15.5.4.20-4-18: FAIL
+# Bug? String.prototype.trim handles whitepace and lineterminators
+# (\\uFEFF\\uFEFF)
+15.5.4.20-4-34: FAIL
+# Bug? Date Time String Format - specified default values will be set for all
+# optional fields(MM, DD, mm, ss and time zone) when they are absent
+15.9.1.15-1: FAIL
+# Bug? Date.prototype.toISOString - RangeError is thrown when value of date is
+# Date(1970, 0, -99999999, 0, 0, 0, -1), the time zone is UTC(0)
+15.9.5.43-0-8: FAIL
+# Bug? Date.prototype.toISOString - RangeError is not thrown when value of date
+# is Date(1970, 0, 100000001, 0, 0, 0, -1), the time zone is UTC(0)
+15.9.5.43-0-11: FAIL
+# Bug? Date.prototype.toISOString - RangeError is not thrown when value of date
+# is Date(1970, 0, 100000001, 0, 0, 0, 0), the time zone is UTC(0)
+15.9.5.43-0-12: FAIL
+# Bug? Date.prototype.toISOString - RangeError is thrown when value of date is
+# Date(1970, 0, 100000001, 0, 0, 0, 1), the time zone is UTC(0)
+15.9.5.43-0-13: FAIL
+# Bug? Date.prototype.toISOString - when value of year is -Infinity
+# Date.prototype.toISOString throw the RangeError
+15.9.5.43-0-14: FAIL
+# Bug? Date.prototype.toISOString - value of year is Infinity
+# Date.prototype.toISOString throw the RangeError
+15.9.5.43-0-15: FAIL
+# Bug? RegExp - the thrown error is SyntaxError instead of RegExpError when 'F'
+# contains any character other than 'g', 'i', or 'm'
+15.10.4.1-3: FAIL
+# Bug? RegExp.prototype is itself a RegExp
+15.10.6: FAIL
+# Bug? RegExp.prototype.source is of type String
+15.10.7.1-1: FAIL
+# Bug? RegExp.prototype.source is a data property with default attribute values
+# (false)
+15.10.7.1-2: FAIL
+# Bug? RegExp.prototype.global is of type Boolean
+15.10.7.2-1: FAIL
+# Bug? RegExp.prototype.global is a data property with default attribute values
+# (false)
+15.10.7.2-2: FAIL
+# Bug? RegExp.prototype.ignoreCase is of type Boolean
+15.10.7.3-1: FAIL
+# Bug? RegExp.prototype.ignoreCase is a data property with default attribute
+# values (false)
+15.10.7.3-2: FAIL
+# Bug? RegExp.prototype.multiline is of type Boolean
+15.10.7.4-1: FAIL
+# Bug? RegExp.prototype.multiline is a data property with default attribute
+# values (false)
+15.10.7.4-2: FAIL
+# Bug? RegExp.prototype.lastIndex is of type Number
+15.10.7.5-1: FAIL
+# Bug? RegExp.prototype.lastIndex is a data property with specified attribute
+# values
+15.10.7.5-2: FAIL
+# Bug? Error.prototype.toString return the value of 'msg' when 'name' is empty
+# string and 'msg' isn't undefined
+15.11.4.4-8-1: FAIL
diff --git a/test/test262/testcfg.py b/test/test262/testcfg.py
new file mode 100644
index 0000000..aa1212e
--- /dev/null
+++ b/test/test262/testcfg.py
@@ -0,0 +1,123 @@
+# Copyright 2011 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import test
+import os
+from os.path import join, exists
+
+
+TEST_262_HARNESS = ['sta.js']
+
+
+class Test262TestCase(test.TestCase):
+
+ def __init__(self, filename, path, context, root, mode, framework):
+ super(Test262TestCase, self).__init__(context, path, mode)
+ self.filename = filename
+ self.framework = framework
+ self.root = root
+
+ def IsNegative(self):
+ return self.filename.endswith('-n.js')
+
+ def GetLabel(self):
+ return "%s test262 %s %s" % (self.mode, self.GetGroup(), self.GetName())
+
+ def IsFailureOutput(self, output):
+ if output.exit_code != 0:
+ return True
+ return 'FAILED!' in output.stdout
+
+ def GetCommand(self):
+ result = self.context.GetVmCommand(self, self.mode)
+ result += ['-e', 'var window = this']
+ result += self.framework
+ result.append(self.filename)
+ return result
+
+ def GetName(self):
+ return self.path[-1]
+
+ def GetGroup(self):
+ return self.path[0]
+
+ def GetSource(self):
+ return open(self.filename).read()
+
+
+class Test262TestConfiguration(test.TestConfiguration):
+
+ def __init__(self, context, root):
+ super(Test262TestConfiguration, self).__init__(context, root)
+
+ def AddIETestCenter(self, tests, current_path, path, mode):
+ current_root = join(self.root, 'data', 'test', 'suite', 'ietestcenter')
+ harness = [join(self.root, 'data', 'test', 'harness', f)
+ for f in TEST_262_HARNESS]
+ harness += [join(self.root, 'harness-adapt.js')]
+ for root, dirs, files in os.walk(current_root):
+ for dotted in [x for x in dirs if x.startswith('.')]:
+ dirs.remove(dotted)
+ dirs.sort()
+ root_path = root[len(self.root):].split(os.path.sep)
+ root_path = current_path + [x for x in root_path if x]
+ files.sort()
+ for file in files:
+ if file.endswith('.js'):
+ if self.Contains(path, root_path):
+ test_path = ['ietestcenter', file[:-3]]
+ test = Test262TestCase(join(root, file), test_path, self.context,
+ self.root, mode, harness)
+ tests.append(test)
+
+ def AddSputnikConvertedTests(self, tests, current_path, path, mode):
+ # To be enabled
+ pass
+
+ def AddSputnikTests(self, tests, current_path, path, mode):
+ # To be enabled
+ pass
+
+ def ListTests(self, current_path, path, mode, variant_flags):
+ tests = []
+ self.AddIETestCenter(tests, current_path, path, mode)
+ self.AddSputnikConvertedTests(tests, current_path, path, mode)
+ self.AddSputnikTests(tests, current_path, path, mode)
+ return tests
+
+ def GetBuildRequirements(self):
+ return ['sample', 'sample=shell']
+
+ def GetTestStatus(self, sections, defs):
+ status_file = join(self.root, 'test262.status')
+ if exists(status_file):
+ test.ReadConfigurationInto(status_file, sections, defs)
+
+
+def GetConfiguration(context, root):
+ return Test262TestConfiguration(context, root)
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 31a5f01..8804454 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -41,6 +41,7 @@
'ENABLE_LOGGING_AND_PROFILING',
'ENABLE_DEBUGGER_SUPPORT',
'ENABLE_VMSTATE_TRACKING',
+ 'V8_FAST_TLS',
],
'conditions': [
['OS!="mac"', {
@@ -437,6 +438,9 @@
'../../src/objects.h',
'../../src/parser.cc',
'../../src/parser.h',
+ '../../src/platform-tls-mac.h',
+ '../../src/platform-tls-win32.h',
+ '../../src/platform-tls.h',
'../../src/platform.h',
'../../src/preparse-data.cc',
'../../src/preparse-data.h',
@@ -480,6 +484,7 @@
'../../src/serialize.cc',
'../../src/serialize.h',
'../../src/shell.h',
+ '../../src/small-pointer-list.h',
'../../src/smart-pointer.h',
'../../src/snapshot-common.cc',
'../../src/snapshot.h',
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index f7eafbd..386e7f0 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -914,6 +914,9 @@
89F3605A12DCDF6400ACF8A6 /* lithium-codegen-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-codegen-x64.cc"; path = "x64/lithium-codegen-x64.cc"; sourceTree = "<group>"; };
89FB0E360F8E531900B04B3C /* d8-posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-posix.cc"; path = "../src/d8-posix.cc"; sourceTree = "<group>"; };
89FB0E370F8E531900B04B3C /* d8-windows.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-windows.cc"; path = "../src/d8-windows.cc"; sourceTree = "<group>"; };
+ 9C1F8E1D133906180068B362 /* small-pointer-list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "small-pointer-list.h"; sourceTree = "<group>"; };
+ 9C76176D133FB7740057370B /* platform-tls-mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "platform-tls-mac.h"; sourceTree = "<group>"; };
+ 9C8E8061133CF772004058A5 /* platform-tls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "platform-tls.h"; sourceTree = "<group>"; };
9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "heap-profiler.cc"; sourceTree = "<group>"; };
9F11D99F105AF0A300EBE5B2 /* heap-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "heap-profiler.h"; sourceTree = "<group>"; };
9F2B370E114FF62D007CDAF4 /* circular-queue-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "circular-queue-inl.h"; sourceTree = "<group>"; };
@@ -1237,6 +1240,8 @@
897FF1670E719B8F00D62E90 /* platform-macos.cc */,
897FF1680E719B8F00D62E90 /* platform-nullos.cc */,
893A72230F7B0FF200303DD2 /* platform-posix.cc */,
+ 9C76176D133FB7740057370B /* platform-tls-mac.h */,
+ 9C8E8061133CF772004058A5 /* platform-tls.h */,
897FF1690E719B8F00D62E90 /* platform-win32.cc */,
897FF16A0E719B8F00D62E90 /* platform.h */,
893E249512B14B3D0083370F /* preparse-data.cc */,
@@ -1283,6 +1288,7 @@
897FF17B0E719B8F00D62E90 /* serialize.h */,
897FF17C0E719B8F00D62E90 /* shell.h */,
893E24A012B14B3D0083370F /* simulator.h */,
+ 9C1F8E1D133906180068B362 /* small-pointer-list.h */,
897FF1810E719B8F00D62E90 /* smart-pointer.h */,
897FF1820E719B8F00D62E90 /* snapshot-common.cc */,
897FF1830E719B8F00D62E90 /* snapshot-empty.cc */,
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
index 0156616..a005f7a 100644
--- a/tools/visual_studio/v8_base.vcproj
+++ b/tools/visual_studio/v8_base.vcproj
@@ -870,6 +870,14 @@
>
</File>
<File
+ RelativePath="..\..\src\platform-tls-win32.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\platform-tls.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\platform-win32.cc"
>
</File>
@@ -1026,6 +1034,10 @@
>
</File>
<File
+ RelativePath="..\..\src\small-pointer-list.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\snapshot-common.cc"
>
</File>
diff --git a/tools/visual_studio/v8_base_arm.vcproj b/tools/visual_studio/v8_base_arm.vcproj
index 6ae962c..87c178a 100644
--- a/tools/visual_studio/v8_base_arm.vcproj
+++ b/tools/visual_studio/v8_base_arm.vcproj
@@ -984,6 +984,10 @@
>
</File>
<File
+ RelativePath="..\..\src\small-pointer-list.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\snapshot-common.cc"
>
</File>
diff --git a/tools/visual_studio/v8_base_x64.vcproj b/tools/visual_studio/v8_base_x64.vcproj
index dc2167b..de921bc 100644
--- a/tools/visual_studio/v8_base_x64.vcproj
+++ b/tools/visual_studio/v8_base_x64.vcproj
@@ -1026,6 +1026,10 @@
>
</File>
<File
+ RelativePath="..\..\src\small-pointer-list.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\snapshot-common.cc"
>
</File>