Version 3.9.8
Fixed memory leak and missing #include in StartupDataDecompressor (issue 1960).
Renamed static methods to avoid shadowing virtual methods and fix Clang C++11 compile error.
Fixed sequence of element access in array builtins (issue 1790).
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@10776 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/.gitignore b/.gitignore
index b61faef..088daea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,10 +23,10 @@
/build/gyp
/obj/
/out/
-/test/es5conform/data/
-/test/mozilla/data/
-/test/sputnik/sputniktests/
-/test/test262/data/
+/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 f0ab6f0..e7a53b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2012-02-21: Version 3.9.8
+
+ Fixed memory leak and missing #include in StartupDataDecompressor
+ (issue 1960).
+
+ Renamed static methods to avoid shadowing virtual methods and fix Clang
+ C++11 compile error.
+
+ Fixed sequence of element access in array builtins (issue 1790).
+
+ Performance and stability improvements on all platforms.
+
+
2012-02-16: Version 3.9.7
Fixed V8 issues 1322, 1878, 1942, 1945 and Chromium issue 113924.
diff --git a/build/common.gypi b/build/common.gypi
index 548df7b..9976d25 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -306,7 +306,7 @@
}],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
- '-Wnon-virtual-dtor' ],
+ '-Wnon-virtual-dtor', '-Woverloaded-virtual' ],
}],
],
}, # Debug
diff --git a/include/v8.h b/include/v8.h
index 66a649d..524fcb2 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1198,7 +1198,7 @@
* passed in as parameters.
*/
V8EXPORT static Local<String> Concat(Handle<String> left,
- Handle<String>right);
+ Handle<String> right);
/**
* Creates a new external string using the data defined in the given
@@ -3850,7 +3850,7 @@
static const int kFullStringRepresentationMask = 0x07;
static const int kExternalTwoByteRepresentationTag = 0x02;
- static const int kJSObjectType = 0xa7;
+ static const int kJSObjectType = 0xa8;
static const int kFirstNonstringType = 0x80;
static const int kForeignType = 0x85;
diff --git a/src/api.cc b/src/api.cc
index 2f8f1d1..67fded8 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -42,6 +42,9 @@
#include "global-handles.h"
#include "heap-profiler.h"
#include "messages.h"
+#ifdef COMPRESS_STARTUP_DATA_BZ2
+#include "natives.h"
+#endif
#include "parser.h"
#include "platform.h"
#include "profile-generator-inl.h"
@@ -357,6 +360,7 @@
compressed_data[i].data = decompressed;
}
V8::SetDecompressedStartupData(compressed_data);
+ i::DeleteArray(compressed_data);
return 0;
}
diff --git a/src/apinatives.js b/src/apinatives.js
index e94da9f..79b41dd 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -37,8 +37,8 @@
}
-const kApiFunctionCache = {};
-const functionCache = kApiFunctionCache;
+var kApiFunctionCache = {};
+var functionCache = kApiFunctionCache;
function Instantiate(data, name) {
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index ec119d8..0e5ac0f 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -2093,19 +2093,18 @@
}
+LInstruction* LChunkBuilder::DoFastLiteral(HFastLiteral* instr) {
+ return MarkAsCall(DefineFixed(new LFastLiteral, r0), instr);
+}
+
+
LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr);
}
-LInstruction* LChunkBuilder::DoObjectLiteralFast(HObjectLiteralFast* instr) {
- return MarkAsCall(DefineFixed(new LObjectLiteralFast, r0), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoObjectLiteralGeneric(
- HObjectLiteralGeneric* instr) {
- return MarkAsCall(DefineFixed(new LObjectLiteralGeneric, r0), instr);
+LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
+ return MarkAsCall(DefineFixed(new LObjectLiteral, r0), instr);
}
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index f22a49f..d26643a 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -93,6 +93,7 @@
V(DivI) \
V(DoubleToI) \
V(ElementsKind) \
+ V(FastLiteral) \
V(FixedArrayBaseLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
@@ -135,8 +136,7 @@
V(NumberTagD) \
V(NumberTagI) \
V(NumberUntagD) \
- V(ObjectLiteralFast) \
- V(ObjectLiteralGeneric) \
+ V(ObjectLiteral) \
V(OsrEntry) \
V(OuterContext) \
V(Parameter) \
@@ -1917,6 +1917,13 @@
};
+class LFastLiteral: public LTemplateInstruction<1, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(FastLiteral, "fast-literal")
+ DECLARE_HYDROGEN_ACCESSOR(FastLiteral)
+};
+
+
class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
@@ -1924,17 +1931,10 @@
};
-class LObjectLiteralFast: public LTemplateInstruction<1, 0, 0> {
+class LObjectLiteral: public LTemplateInstruction<1, 0, 0> {
public:
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralFast, "object-literal-fast")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralFast)
-};
-
-
-class LObjectLiteralGeneric: public LTemplateInstruction<1, 0, 0> {
- public:
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralGeneric, "object-literal-generic")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralGeneric)
+ DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
+ DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
};
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index f845f47..97e743a 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -4380,26 +4380,35 @@
ASSERT(!source.is(r2));
ASSERT(!result.is(r2));
+ // Only elements backing stores for non-COW arrays need to be copied.
+ Handle<FixedArrayBase> elements(object->elements());
+ bool has_elements = elements->length() > 0 &&
+ elements->map() != isolate()->heap()->fixed_cow_array_map();
+
// Increase the offset so that subsequent objects end up right after
- // this one.
- int current_offset = *offset;
- int size = object->map()->instance_size();
- *offset += size;
+ // this object and its backing store.
+ int object_offset = *offset;
+ int object_size = object->map()->instance_size();
+ int elements_offset = *offset + object_size;
+ int elements_size = has_elements ? elements->Size() : 0;
+ *offset += object_size + elements_size;
// Copy object header.
ASSERT(object->properties()->length() == 0);
- ASSERT(object->elements()->length() == 0 ||
- object->elements()->map() == isolate()->heap()->fixed_cow_array_map());
int inobject_properties = object->map()->inobject_properties();
- int header_size = size - inobject_properties * kPointerSize;
+ int header_size = object_size - inobject_properties * kPointerSize;
for (int i = 0; i < header_size; i += kPointerSize) {
- __ ldr(r2, FieldMemOperand(source, i));
- __ str(r2, FieldMemOperand(result, current_offset + i));
+ if (has_elements && i == JSObject::kElementsOffset) {
+ __ add(r2, result, Operand(elements_offset));
+ } else {
+ __ ldr(r2, FieldMemOperand(source, i));
+ }
+ __ str(r2, FieldMemOperand(result, object_offset + i));
}
// Copy in-object properties.
for (int i = 0; i < inobject_properties; i++) {
- int total_offset = current_offset + object->GetInObjectPropertyOffset(i);
+ int total_offset = object_offset + object->GetInObjectPropertyOffset(i);
Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i));
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
@@ -4415,10 +4424,41 @@
__ str(r2, FieldMemOperand(result, total_offset));
}
}
+
+ // Copy elements backing store header.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ if (has_elements) {
+ __ LoadHeapObject(source, elements);
+ for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) {
+ __ ldr(r2, FieldMemOperand(source, i));
+ __ str(r2, FieldMemOperand(result, elements_offset + i));
+ }
+ }
+
+ // Copy elements backing store content.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ int elements_length = has_elements ? elements->length() : 0;
+ for (int i = 0; i < elements_length; i++) {
+ int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
+ Handle<Object> value = JSObject::GetElement(object, i);
+ if (value->IsJSObject()) {
+ Handle<JSObject> value_object = Handle<JSObject>::cast(value);
+ __ add(r2, result, Operand(*offset));
+ __ str(r2, FieldMemOperand(result, total_offset));
+ __ LoadHeapObject(source, value_object);
+ EmitDeepCopy(value_object, result, source, offset);
+ } else if (value->IsHeapObject()) {
+ __ LoadHeapObject(r2, Handle<HeapObject>::cast(value));
+ __ str(r2, FieldMemOperand(result, total_offset));
+ } else {
+ __ mov(r2, Operand(value));
+ __ str(r2, FieldMemOperand(result, total_offset));
+ }
+ }
}
-void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) {
+void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
int size = instr->hydrogen()->total_size();
// Allocate all objects that are part of the literal in one big
@@ -4440,7 +4480,7 @@
}
-void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
+void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
Handle<FixedArray> literals(instr->environment()->closure()->literals());
Handle<FixedArray> constant_properties =
instr->hydrogen()->constant_properties();
diff --git a/src/array.js b/src/array.js
index 16e37c5..daa75d5 100644
--- a/src/array.js
+++ b/src/array.js
@@ -27,7 +27,7 @@
// This file relies on the fact that the following declarations have been made
// in runtime.js:
-// const $Array = global.Array;
+// var $Array = global.Array;
// -------------------------------------------------------------------
@@ -757,7 +757,7 @@
}
var receiver = %GetDefaultReceiver(comparefn);
- function InsertionSort(a, from, to) {
+ var InsertionSort = function InsertionSort(a, from, to) {
for (var i = from + 1; i < to; i++) {
var element = a[i];
for (var j = i - 1; j >= from; j--) {
@@ -771,9 +771,9 @@
}
a[j + 1] = element;
}
- }
+ };
- function QuickSort(a, from, to) {
+ var QuickSort = function QuickSort(a, from, to) {
// Insertion sort is faster for short arrays.
if (to - from <= 10) {
InsertionSort(a, from, to);
@@ -841,12 +841,12 @@
}
QuickSort(a, from, low_end);
QuickSort(a, high_start, to);
- }
+ };
// Copy elements in the range 0..length from obj's prototype chain
// to obj itself, if obj has holes. Return one more than the maximal index
// of a prototype property.
- function CopyFromPrototype(obj, length) {
+ var CopyFromPrototype = function CopyFromPrototype(obj, length) {
var max = 0;
for (var proto = obj.__proto__; proto; proto = proto.__proto__) {
var indices = %GetArrayKeys(proto, length);
@@ -873,12 +873,12 @@
}
}
return max;
- }
+ };
// Set a value of "undefined" on all indices in the range from..to
// where a prototype of obj has an element. I.e., shadow all prototype
// elements in that range.
- function ShadowPrototypeElements(obj, from, to) {
+ var ShadowPrototypeElements = function(obj, from, to) {
for (var proto = obj.__proto__; proto; proto = proto.__proto__) {
var indices = %GetArrayKeys(proto, to);
if (indices.length > 0) {
@@ -901,9 +901,9 @@
}
}
}
- }
+ };
- function SafeRemoveArrayHoles(obj) {
+ var SafeRemoveArrayHoles = function SafeRemoveArrayHoles(obj) {
// Copy defined elements from the end to fill in all holes and undefineds
// in the beginning of the array. Write undefineds and holes at the end
// after loop is finished.
@@ -958,7 +958,7 @@
// Return the number of defined elements.
return first_undefined;
- }
+ };
var length = TO_UINT32(this.length);
if (length < 2) return this;
@@ -1024,10 +1024,10 @@
var accumulator = new InternalArray();
var accumulator_length = 0;
for (var i = 0; i < length; i++) {
- var current = array[i];
- if (!IS_UNDEFINED(current) || i in array) {
- if (%_CallFunction(receiver, current, i, array, f)) {
- accumulator[accumulator_length++] = current;
+ if (i in array) {
+ var element = array[i];
+ if (%_CallFunction(receiver, element, i, array, f)) {
+ accumulator[accumulator_length++] = element;
}
}
}
@@ -1057,9 +1057,9 @@
}
for (var i = 0; i < length; i++) {
- var current = array[i];
- if (!IS_UNDEFINED(current) || i in array) {
- %_CallFunction(receiver, current, i, array, f);
+ if (i in array) {
+ var element = array[i];
+ %_CallFunction(receiver, element, i, array, f);
}
}
}
@@ -1088,9 +1088,9 @@
}
for (var i = 0; i < length; i++) {
- var current = array[i];
- if (!IS_UNDEFINED(current) || i in array) {
- if (%_CallFunction(receiver, current, i, array, f)) return true;
+ if (i in array) {
+ var element = array[i];
+ if (%_CallFunction(receiver, element, i, array, f)) return true;
}
}
return false;
@@ -1118,9 +1118,9 @@
}
for (var i = 0; i < length; i++) {
- var current = array[i];
- if (!IS_UNDEFINED(current) || i in array) {
- if (!%_CallFunction(receiver, current, i, array, f)) return false;
+ if (i in array) {
+ var element = array[i];
+ if (!%_CallFunction(receiver, element, i, array, f)) return false;
}
}
return true;
@@ -1149,9 +1149,9 @@
var result = new $Array();
var accumulator = new InternalArray(length);
for (var i = 0; i < length; i++) {
- var current = array[i];
- if (!IS_UNDEFINED(current) || i in array) {
- accumulator[i] = %_CallFunction(receiver, current, i, array, f);
+ if (i in array) {
+ var element = array[i];
+ accumulator[i] = %_CallFunction(receiver, element, i, array, f);
}
}
%MoveArrayContents(accumulator, result);
@@ -1308,8 +1308,8 @@
var receiver = %GetDefaultReceiver(callback);
for (; i < length; i++) {
- var element = array[i];
- if (!IS_UNDEFINED(element) || i in array) {
+ if (i in array) {
+ var element = array[i];
current = %_CallFunction(receiver, current, element, i, array, callback);
}
}
@@ -1345,8 +1345,8 @@
var receiver = %GetDefaultReceiver(callback);
for (; i >= 0; i--) {
- var element = array[i];
- if (!IS_UNDEFINED(element) || i in array) {
+ if (i in array) {
+ var element = array[i];
current = %_CallFunction(receiver, current, element, i, array, callback);
}
}
@@ -1373,7 +1373,7 @@
var specialFunctions = %SpecialArrayFunctions({});
- function getFunction(name, jsBuiltin, len) {
+ var getFunction = function(name, jsBuiltin, len) {
var f = jsBuiltin;
if (specialFunctions.hasOwnProperty(name)) {
f = specialFunctions[name];
@@ -1382,7 +1382,7 @@
%FunctionSetLength(f, len);
}
return f;
- }
+ };
// Set up non-enumerable functions of the Array.prototype object and
// set their names.
diff --git a/src/ast.cc b/src/ast.cc
index 43f1ed9..7e886fa 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1010,7 +1010,6 @@
INCREASE_NODE_COUNT(Conditional)
INCREASE_NODE_COUNT(Literal)
INCREASE_NODE_COUNT(ObjectLiteral)
-INCREASE_NODE_COUNT(FunctionLiteral)
INCREASE_NODE_COUNT(Assignment)
INCREASE_NODE_COUNT(Throw)
INCREASE_NODE_COUNT(Property)
@@ -1084,6 +1083,12 @@
}
+void AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
+ increase_node_count();
+ add_flag(kDontInline);
+}
+
+
void AstConstructionVisitor::VisitSharedFunctionInfoLiteral(
SharedFunctionInfoLiteral* node) {
increase_node_count();
diff --git a/src/ast.h b/src/ast.h
index a634e5e..60f9d43 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -548,17 +548,17 @@
public:
DECLARE_NODE_TYPE(ModuleVariable)
- Variable* var() const { return var_; }
+ VariableProxy* proxy() const { return proxy_; }
protected:
template<class> friend class AstNodeFactory;
- explicit ModuleVariable(Variable* var)
- : var_(var) {
+ explicit ModuleVariable(VariableProxy* proxy)
+ : proxy_(proxy) {
}
private:
- Variable* var_;
+ VariableProxy* proxy_;
};
@@ -2536,19 +2536,19 @@
VISIT_AND_RETURN(ModuleLiteral, module)
}
- ModuleVariable* NewModuleVariable(Variable* var) {
- ModuleVariable* module = new(zone_) ModuleVariable(var);
- VISIT_AND_RETURN(ModuleLiteral, module)
+ ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
+ ModuleVariable* module = new(zone_) ModuleVariable(proxy);
+ VISIT_AND_RETURN(ModuleVariable, module)
}
ModulePath* NewModulePath(Module* origin, Handle<String> name) {
ModulePath* module = new(zone_) ModulePath(origin, name);
- VISIT_AND_RETURN(ModuleLiteral, module)
+ VISIT_AND_RETURN(ModulePath, module)
}
ModuleUrl* NewModuleUrl(Handle<String> url) {
ModuleUrl* module = new(zone_) ModuleUrl(url);
- VISIT_AND_RETURN(ModuleLiteral, module)
+ VISIT_AND_RETURN(ModuleUrl, module)
}
Block* NewBlock(ZoneStringList* labels,
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index ef53df4..0f5b9c8 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -172,6 +172,10 @@
Handle<JSFunction> GetThrowTypeErrorFunction();
void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
+
+ // Make the "arguments" and "caller" properties throw a TypeError on access.
+ void PoisonArgumentsAndCaller(Handle<Map> map);
+
// Creates the global objects using the global and the template passed in
// through the API. We call this regardless of whether we are building a
// context from scratch or using a deserialized one from the partial snapshot
@@ -192,7 +196,7 @@
// detached from the other objects in the snapshot.
void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
// New context initialization. Used for creating a context from scratch.
- void InitializeGlobal(Handle<GlobalObject> inner_global,
+ bool InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> empty_function);
void InitializeExperimentalGlobal();
// Installs the contents of the native .js files on the global objects.
@@ -256,14 +260,10 @@
Handle<Map> CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
- Handle<JSFunction> empty_function,
- Handle<AccessorPair> arguments_callbacks,
- Handle<AccessorPair> caller_callbacks);
+ Handle<JSFunction> empty_function);
Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
- PrototypePropertyMode propertyMode,
- Handle<AccessorPair> arguments,
- Handle<AccessorPair> caller);
+ PrototypePropertyMode propertyMode);
static bool CompileBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
@@ -384,44 +384,40 @@
Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
PrototypePropertyMode prototypeMode) {
- Handle<DescriptorArray> descriptors =
- factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
- ? 4
- : 5);
- PropertyAttributes attributes =
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+ int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
+ Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE | READ_ONLY);
DescriptorArray::WhitenessWitness witness(*descriptors);
{ // Add length.
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
- CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
+ CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
descriptors->Set(0, &d, witness);
}
{ // Add name.
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
- CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
+ CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
descriptors->Set(1, &d, witness);
}
{ // Add arguments.
- Handle<Foreign> foreign =
- factory()->NewForeign(&Accessors::FunctionArguments);
- CallbacksDescriptor d(*factory()->arguments_symbol(), *foreign, attributes);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionArguments));
+ CallbacksDescriptor d(*factory()->arguments_symbol(), *f, attribs);
descriptors->Set(2, &d, witness);
}
{ // Add caller.
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionCaller);
- CallbacksDescriptor d(*factory()->caller_symbol(), *foreign, attributes);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionCaller));
+ CallbacksDescriptor d(*factory()->caller_symbol(), *f, attribs);
descriptors->Set(3, &d, witness);
}
if (prototypeMode != DONT_ADD_PROTOTYPE) {
// Add prototype.
if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
- attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+ attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
}
- Handle<Foreign> foreign =
- factory()->NewForeign(&Accessors::FunctionPrototype);
- CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
descriptors->Set(4, &d, witness);
}
descriptors->Sort(witness);
@@ -532,47 +528,42 @@
Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
- PrototypePropertyMode prototypeMode,
- Handle<AccessorPair> arguments,
- Handle<AccessorPair> caller) {
- Handle<DescriptorArray> descriptors =
- factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
- ? 4
- : 5);
- PropertyAttributes attributes = static_cast<PropertyAttributes>(
+ PrototypePropertyMode prototypeMode) {
+ int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
+ Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE);
DescriptorArray::WhitenessWitness witness(*descriptors);
- { // length
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
- CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
+ { // Add length.
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
+ CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
descriptors->Set(0, &d, witness);
}
- { // name
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
- CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
+ { // Add name.
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
+ CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
descriptors->Set(1, &d, witness);
}
- { // arguments
- CallbacksDescriptor d(*factory()->arguments_symbol(),
- *arguments,
- attributes);
+ { // Add arguments.
+ Handle<AccessorPair> arguments(factory()->NewAccessorPair());
+ CallbacksDescriptor d(*factory()->arguments_symbol(), *arguments, attribs);
descriptors->Set(2, &d, witness);
}
- { // caller
- CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attributes);
+ { // Add caller.
+ Handle<AccessorPair> caller(factory()->NewAccessorPair());
+ CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attribs);
descriptors->Set(3, &d, witness);
}
- // prototype
if (prototypeMode != DONT_ADD_PROTOTYPE) {
+ // Add prototype.
if (prototypeMode != ADD_WRITEABLE_PROTOTYPE) {
- attributes = static_cast<PropertyAttributes>(attributes | READ_ONLY);
+ attribs = static_cast<PropertyAttributes>(attribs | READ_ONLY);
}
- Handle<Foreign> foreign =
- factory()->NewForeign(&Accessors::FunctionPrototype);
- CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
descriptors->Set(4, &d, witness);
}
@@ -603,14 +594,10 @@
Handle<Map> Genesis::CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
- Handle<JSFunction> empty_function,
- Handle<AccessorPair> arguments_callbacks,
- Handle<AccessorPair> caller_callbacks) {
+ Handle<JSFunction> empty_function) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Handle<DescriptorArray> descriptors =
- ComputeStrictFunctionInstanceDescriptor(prototype_mode,
- arguments_callbacks,
- caller_callbacks);
+ ComputeStrictFunctionInstanceDescriptor(prototype_mode);
map->set_instance_descriptors(*descriptors);
map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
map->set_prototype(*empty_function);
@@ -619,23 +606,15 @@
void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
- // Create the callbacks arrays for ThrowTypeError functions.
- // The get/set callacks are filled in after the maps are created below.
- Factory* factory = empty->GetIsolate()->factory();
- Handle<AccessorPair> arguments(factory->NewAccessorPair());
- Handle<AccessorPair> caller(factory->NewAccessorPair());
-
// Allocate map for the strict mode function instances.
Handle<Map> strict_mode_function_instance_map =
- CreateStrictModeFunctionMap(
- ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
+ CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
global_context()->set_strict_mode_function_instance_map(
*strict_mode_function_instance_map);
// Allocate map for the prototype-less strict mode instances.
Handle<Map> strict_mode_function_without_prototype_map =
- CreateStrictModeFunctionMap(
- DONT_ADD_PROTOTYPE, empty, arguments, caller);
+ CreateStrictModeFunctionMap(DONT_ADD_PROTOTYPE, empty);
global_context()->set_strict_mode_function_without_prototype_map(
*strict_mode_function_without_prototype_map);
@@ -643,26 +622,38 @@
// only for processing of builtins.
// Later the map is replaced with writable prototype map, allocated below.
Handle<Map> strict_mode_function_map =
- CreateStrictModeFunctionMap(
- ADD_READONLY_PROTOTYPE, empty, arguments, caller);
+ CreateStrictModeFunctionMap(ADD_READONLY_PROTOTYPE, empty);
global_context()->set_strict_mode_function_map(
*strict_mode_function_map);
// The final map for the strict mode functions. Writeable prototype.
// This map is installed in MakeFunctionInstancePrototypeWritable.
strict_mode_function_instance_map_writable_prototype_ =
- CreateStrictModeFunctionMap(
- ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
-
- // Create the ThrowTypeError function instance.
- Handle<JSFunction> throw_function =
- GetThrowTypeErrorFunction();
+ CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
// Complete the callbacks.
- arguments->set_getter(*throw_function);
- arguments->set_setter(*throw_function);
- caller->set_getter(*throw_function);
- caller->set_setter(*throw_function);
+ PoisonArgumentsAndCaller(strict_mode_function_instance_map);
+ PoisonArgumentsAndCaller(strict_mode_function_without_prototype_map);
+ PoisonArgumentsAndCaller(strict_mode_function_map);
+ PoisonArgumentsAndCaller(
+ strict_mode_function_instance_map_writable_prototype_);
+}
+
+
+static void SetAccessors(Handle<Map> map,
+ Handle<String> name,
+ Handle<JSFunction> func) {
+ DescriptorArray* descs = map->instance_descriptors();
+ int number = descs->Search(*name);
+ AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
+ accessors->set_getter(*func);
+ accessors->set_setter(*func);
+}
+
+
+void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
+ SetAccessors(map, factory()->arguments_symbol(), GetThrowTypeErrorFunction());
+ SetAccessors(map, factory()->caller_symbol(), GetThrowTypeErrorFunction());
}
@@ -837,7 +828,7 @@
// This is only called if we are not using snapshots. The equivalent
// work in the snapshot case is done in HookUpInnerGlobal.
-void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
+bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> empty_function) {
// --- G l o b a l C o n t e x t ---
// Use the empty function as closure (no scope info).
@@ -1041,7 +1032,10 @@
Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
Handle<JSFunction> cons = factory->NewFunction(name,
factory->the_hole_value());
- cons->SetInstancePrototype(global_context()->initial_object_prototype());
+ { MaybeObject* result = cons->SetInstancePrototype(
+ global_context()->initial_object_prototype());
+ if (result->IsFailure()) return false;
+ }
cons->SetInstanceClassName(*name);
Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
ASSERT(json_object->IsJSObject());
@@ -1252,6 +1246,7 @@
global_context()->set_random_seed(*zeroed_byte_array);
memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
}
+ return true;
}
@@ -2323,7 +2318,7 @@
Handle<JSGlobalProxy> global_proxy =
CreateNewGlobals(global_template, global_object, &inner_global);
HookUpGlobalProxy(inner_global, global_proxy);
- InitializeGlobal(inner_global, empty_function);
+ if (!InitializeGlobal(inner_global, empty_function)) return;
InstallJSFunctionResultCaches();
InitializeNormalizedMapCaches();
if (!InstallNatives()) return;
diff --git a/src/collection.js b/src/collection.js
index fcf4d38..75fe3d5 100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -25,10 +25,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"use strict";
-const $Set = global.Set;
-const $Map = global.Map;
-const $WeakMap = global.WeakMap;
+var $Set = global.Set;
+var $Map = global.Map;
+var $WeakMap = global.WeakMap;
//-------------------------------------------------------------------
diff --git a/src/compiler.cc b/src/compiler.cc
index 1a3b4c3..5d7dbd1 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -497,13 +497,6 @@
// for small sources, odds are that there aren't many functions
// that would be compiled lazily anyway, so we skip the preparse step
// in that case too.
- int flags = kNoParsingFlags;
- if ((natives == NATIVES_CODE) || FLAG_allow_natives_syntax) {
- flags |= kAllowNativesSyntax;
- }
- if (natives != NATIVES_CODE && FLAG_harmony_scoping) {
- flags |= EXTENDED_MODE;
- }
// Create a script object describing the script to be compiled.
Handle<Script> script = FACTORY->NewScript(source);
@@ -524,6 +517,7 @@
info.MarkAsGlobal();
info.SetExtension(extension);
info.SetPreParseData(pre_data);
+ if (FLAG_use_strict) info.SetLanguageMode(STRICT_MODE);
result = MakeFunctionInfo(&info);
if (extension == NULL && !result.is_null()) {
compilation_cache->PutScript(source, result);
diff --git a/src/contexts.h b/src/contexts.h
index 1f88c94..af5cb03 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -356,6 +356,10 @@
Map* map = this->map();
return map == map->GetHeap()->block_context_map();
}
+ bool IsModuleContext() {
+ Map* map = this->map();
+ return map == map->GetHeap()->module_context_map();
+ }
// Tells whether the global context is marked with out of memory.
inline bool has_out_of_memory();
diff --git a/src/d8.js b/src/d8.js
index 86b8c81..d136393 100644
--- a/src/d8.js
+++ b/src/d8.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"use strict";
+
String.prototype.startsWith = function (str) {
if (str.length > this.length) {
return false;
@@ -76,7 +78,7 @@
// Global object holding debugger related constants and state.
-const Debug = {};
+var Debug = {};
// Debug events which can occour in the V8 JavaScript engine. These originate
@@ -111,7 +113,7 @@
// Current debug state.
-const kNoFrame = -1;
+var kNoFrame = -1;
Debug.State = {
currentFrame: kNoFrame,
displaySourceStartLine: -1,
@@ -123,8 +125,8 @@
var last_cmd_line = '';
//var lol_is_enabled; // Set to true in d8.cc if LIVE_OBJECT_LIST is defined.
var lol_next_dump_index = 0;
-const kDefaultLolLinesToPrintAtATime = 10;
-const kMaxLolLinesToPrintAtATime = 1000;
+var kDefaultLolLinesToPrintAtATime = 10;
+var kMaxLolLinesToPrintAtATime = 1000;
var repeat_cmd_line = '';
var is_running = true;
@@ -2629,7 +2631,7 @@
// Mapping of some control characters to avoid the \uXXXX syntax for most
// commonly used control cahracters.
-const ctrlCharMap_ = {
+var ctrlCharMap_ = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
@@ -2641,12 +2643,12 @@
// Regular expression testing for ", \ and control characters (0x00 - 0x1F).
-const ctrlCharTest_ = new RegExp('["\\\\\x00-\x1F]');
+var ctrlCharTest_ = new RegExp('["\\\\\x00-\x1F]');
// Regular expression matching ", \ and control characters (0x00 - 0x1F)
// globally.
-const ctrlCharMatch_ = new RegExp('["\\\\\x00-\x1F]', 'g');
+var ctrlCharMatch_ = new RegExp('["\\\\\x00-\x1F]', 'g');
/**
@@ -2688,12 +2690,12 @@
* @return {string} JSON formatted Date value
*/
function DateToISO8601_(value) {
- function f(n) {
+ var f = function(n) {
return n < 10 ? '0' + n : n;
- }
- function g(n) {
+ };
+ var g = function(n) {
return n < 10 ? '00' + n : n < 100 ? '0' + n : n;
- }
+ };
return builtins.GetUTCFullYearFrom(value) + '-' +
f(builtins.GetUTCMonthFrom(value) + 1) + '-' +
f(builtins.GetUTCDateFrom(value)) + 'T' +
diff --git a/src/date.js b/src/date.js
index 999009e..8c51a93 100644
--- a/src/date.js
+++ b/src/date.js
@@ -28,17 +28,16 @@
// This file relies on the fact that the following declarations have been made
// in v8natives.js:
-// const $isFinite = GlobalIsFinite;
+// var $isFinite = GlobalIsFinite;
// -------------------------------------------------------------------
// This file contains date support implemented in JavaScript.
-
// Keep reference to original values of some global properties. This
// has the added benefit that the code in this file is isolated from
// changes to these properties.
-const $Date = global.Date;
+var $Date = global.Date;
// Helper function to throw error.
function ThrowDateTypeError() {
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index 120a297..91c70a0 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -26,14 +26,14 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Default number of frames to include in the response to backtrace request.
-const kDefaultBacktraceLength = 10;
+var kDefaultBacktraceLength = 10;
-const Debug = {};
+var Debug = {};
// Regular expression to skip "crud" at the beginning of a source line which is
// not really code. Currently the regular expression matches whitespace and
// comments.
-const sourceLineBeginningSkip = /^(?:\s*(?:\/\*.*?\*\/)*)*/;
+var sourceLineBeginningSkip = /^(?:\s*(?:\/\*.*?\*\/)*)*/;
// Debug events which can occour in the V8 JavaScript engine. These originate
// from the API include file debug.h.
diff --git a/src/elements.cc b/src/elements.cc
index e54ec62..c15c44d 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -109,30 +109,29 @@
uint32_t key,
JSObject* obj,
Object* receiver) {
- return ElementsAccessorSubclass::Get(
+ return ElementsAccessorSubclass::GetImpl(
BackingStoreClass::cast(backing_store), key, obj, receiver);
}
- static MaybeObject* Get(BackingStoreClass* backing_store,
- uint32_t key,
- JSObject* obj,
- Object* receiver) {
- if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) {
- return backing_store->get(key);
- }
- return backing_store->GetHeap()->the_hole_value();
+ static MaybeObject* GetImpl(BackingStoreClass* backing_store,
+ uint32_t key,
+ JSObject* obj,
+ Object* receiver) {
+ return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
+ ? backing_store->get(key)
+ : backing_store->GetHeap()->the_hole_value();
}
virtual MaybeObject* SetLength(JSObject* obj,
Object* length) {
ASSERT(obj->IsJSArray());
- return ElementsAccessorSubclass::SetLength(
+ return ElementsAccessorSubclass::SetLengthImpl(
BackingStoreClass::cast(obj->elements()), obj, length);
}
- static MaybeObject* SetLength(BackingStoreClass* backing_store,
- JSObject* obj,
- Object* length);
+ static MaybeObject* SetLengthImpl(BackingStoreClass* backing_store,
+ JSObject* obj,
+ Object* length);
virtual MaybeObject* SetCapacityAndLength(JSArray* array,
int capacity,
@@ -167,7 +166,7 @@
}
#endif
BackingStoreClass* backing_store = BackingStoreClass::cast(from);
- uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store);
+ uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
// Optimize if 'other' is empty.
// We cannot optimize if 'this' is empty, as other may have holes.
@@ -176,14 +175,13 @@
// Compute how many elements are not in other.
int extra = 0;
for (uint32_t y = 0; y < len1; y++) {
- if (ElementsAccessorSubclass::HasElementAtIndex(backing_store,
- y,
- holder,
- receiver)) {
+ if (ElementsAccessorSubclass::HasElementAtIndexImpl(
+ backing_store, y, holder, receiver)) {
uint32_t key =
- ElementsAccessorSubclass::GetKeyForIndex(backing_store, y);
+ ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
MaybeObject* maybe_value =
- ElementsAccessorSubclass::Get(backing_store, key, holder, receiver);
+ ElementsAccessorSubclass::GetImpl(backing_store, key,
+ holder, receiver);
Object* value;
if (!maybe_value->ToObject(&value)) return maybe_value;
ASSERT(!value->IsTheHole());
@@ -214,14 +212,13 @@
// Fill in the extra values.
int index = 0;
for (uint32_t y = 0; y < len1; y++) {
- if (ElementsAccessorSubclass::HasElementAtIndex(backing_store,
- y,
- holder,
- receiver)) {
+ if (ElementsAccessorSubclass::HasElementAtIndexImpl(
+ backing_store, y, holder, receiver)) {
uint32_t key =
- ElementsAccessorSubclass::GetKeyForIndex(backing_store, y);
+ ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
MaybeObject* maybe_value =
- ElementsAccessorSubclass::Get(backing_store, key, holder, receiver);
+ ElementsAccessorSubclass::GetImpl(backing_store, key,
+ holder, receiver);
Object* value;
if (!maybe_value->ToObject(&value)) return maybe_value;
if (!value->IsTheHole() && !HasKey(to, value)) {
@@ -235,25 +232,23 @@
}
protected:
- static uint32_t GetCapacity(BackingStoreClass* backing_store) {
+ static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) {
return backing_store->length();
}
virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
- return ElementsAccessorSubclass::GetCapacity(
+ return ElementsAccessorSubclass::GetCapacityImpl(
BackingStoreClass::cast(backing_store));
}
- static bool HasElementAtIndex(BackingStoreClass* backing_store,
- uint32_t index,
- JSObject* holder,
- Object* receiver) {
+ static bool HasElementAtIndexImpl(BackingStoreClass* backing_store,
+ uint32_t index,
+ JSObject* holder,
+ Object* receiver) {
uint32_t key =
- ElementsAccessorSubclass::GetKeyForIndex(backing_store, index);
- MaybeObject* element = ElementsAccessorSubclass::Get(backing_store,
- key,
- holder,
- receiver);
+ ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
+ MaybeObject* element =
+ ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver);
return !element->IsTheHole();
}
@@ -261,18 +256,18 @@
uint32_t index,
JSObject* holder,
Object* receiver) {
- return ElementsAccessorSubclass::HasElementAtIndex(
+ return ElementsAccessorSubclass::HasElementAtIndexImpl(
BackingStoreClass::cast(backing_store), index, holder, receiver);
}
- static uint32_t GetKeyForIndex(BackingStoreClass* backing_store,
- uint32_t index) {
+ static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store,
+ uint32_t index) {
return index;
}
virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
uint32_t index) {
- return ElementsAccessorSubclass::GetKeyForIndex(
+ return ElementsAccessorSubclass::GetKeyForIndexImpl(
BackingStoreClass::cast(backing_store), index);
}
@@ -446,10 +441,10 @@
return obj->GetHeap()->true_value();
}
- static bool HasElementAtIndex(FixedDoubleArray* backing_store,
- uint32_t index,
- JSObject* holder,
- Object* receiver) {
+ static bool HasElementAtIndexImpl(FixedDoubleArray* backing_store,
+ uint32_t index,
+ JSObject* holder,
+ Object* receiver) {
return !backing_store->is_the_hole(index);
}
};
@@ -465,20 +460,19 @@
friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
ExternalArray>;
- static MaybeObject* Get(ExternalArray* backing_store,
- uint32_t key,
- JSObject* obj,
- Object* receiver) {
- if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) {
- return backing_store->get(key);
- } else {
- return backing_store->GetHeap()->undefined_value();
- }
+ static MaybeObject* GetImpl(ExternalArray* backing_store,
+ uint32_t key,
+ JSObject* obj,
+ Object* receiver) {
+ return
+ key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
+ ? backing_store->get(key)
+ : backing_store->GetHeap()->undefined_value();
}
- static MaybeObject* SetLength(ExternalArray* backing_store,
- JSObject* obj,
- Object* length) {
+ static MaybeObject* SetLengthImpl(ExternalArray* backing_store,
+ JSObject* obj,
+ Object* length) {
// External arrays do not support changing their length.
UNREACHABLE();
return obj;
@@ -663,10 +657,10 @@
return DeleteCommon(obj, key, mode);
}
- static MaybeObject* Get(SeededNumberDictionary* backing_store,
- uint32_t key,
- JSObject* obj,
- Object* receiver) {
+ static MaybeObject* GetImpl(SeededNumberDictionary* backing_store,
+ uint32_t key,
+ JSObject* obj,
+ Object* receiver) {
int entry = backing_store->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
Object* element = backing_store->ValueAt(entry);
@@ -683,8 +677,8 @@
return obj->GetHeap()->the_hole_value();
}
- static uint32_t GetKeyForIndex(SeededNumberDictionary* dict,
- uint32_t index) {
+ static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict,
+ uint32_t index) {
Object* key = dict->KeyAt(index);
return Smi::cast(key)->value();
}
@@ -698,10 +692,10 @@
friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
FixedArray>;
- static MaybeObject* Get(FixedArray* parameter_map,
- uint32_t key,
- JSObject* obj,
- Object* receiver) {
+ static MaybeObject* GetImpl(FixedArray* parameter_map,
+ uint32_t key,
+ JSObject* obj,
+ Object* receiver) {
Object* probe = GetParameterMapArg(parameter_map, key);
if (!probe->IsTheHole()) {
Context* context = Context::cast(parameter_map->get(0));
@@ -718,9 +712,9 @@
}
}
- static MaybeObject* SetLength(FixedArray* parameter_map,
- JSObject* obj,
- Object* length) {
+ static MaybeObject* SetLengthImpl(FixedArray* parameter_map,
+ JSObject* obj,
+ Object* length) {
// TODO(mstarzinger): This was never implemented but will be used once we
// correctly implement [[DefineOwnProperty]] on arrays.
UNIMPLEMENTED();
@@ -748,21 +742,21 @@
return obj->GetHeap()->true_value();
}
- static uint32_t GetCapacity(FixedArray* parameter_map) {
+ static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
return Max(static_cast<uint32_t>(parameter_map->length() - 2),
ForArray(arguments)->GetCapacity(arguments));
}
- static uint32_t GetKeyForIndex(FixedArray* dict,
- uint32_t index) {
+ static uint32_t GetKeyForIndexImpl(FixedArray* dict,
+ uint32_t index) {
return index;
}
- static bool HasElementAtIndex(FixedArray* parameter_map,
- uint32_t index,
- JSObject* holder,
- Object* receiver) {
+ static bool HasElementAtIndexImpl(FixedArray* parameter_map,
+ uint32_t index,
+ JSObject* holder,
+ Object* receiver) {
Object* probe = GetParameterMapArg(parameter_map, index);
if (!probe->IsTheHole()) {
return true;
@@ -866,9 +860,9 @@
template <typename ElementsAccessorSubclass, typename BackingStoreClass>
MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>::
- SetLength(BackingStoreClass* backing_store,
- JSObject* obj,
- Object* length) {
+ SetLengthImpl(BackingStoreClass* backing_store,
+ JSObject* obj,
+ Object* length) {
JSArray* array = JSArray::cast(obj);
// Fast case: The new length fits into a Smi.
@@ -917,7 +911,9 @@
MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1);
if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
new_backing_store->set(0, length);
- array->SetContent(new_backing_store);
+ { MaybeObject* result = array->SetContent(new_backing_store);
+ if (result->IsFailure()) return result;
+ }
return array;
}
diff --git a/src/factory.cc b/src/factory.cc
index daf9d64..cc43762 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -148,6 +148,13 @@
}
+Handle<TypeFeedbackInfo> Factory::NewTypeFeedbackInfo() {
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->AllocateTypeFeedbackInfo(),
+ TypeFeedbackInfo);
+}
+
+
// Symbols are created in the old generation (data space).
Handle<String> Factory::LookupSymbol(Vector<const char> string) {
CALL_HEAP_FUNCTION(isolate(),
diff --git a/src/factory.h b/src/factory.h
index 121d34c..786d4a9 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -76,6 +76,8 @@
// Allocates a pre-tenured empty AccessorPair.
Handle<AccessorPair> NewAccessorPair();
+ Handle<TypeFeedbackInfo> NewTypeFeedbackInfo();
+
Handle<String> LookupSymbol(Vector<const char> str);
Handle<String> LookupSymbol(Handle<String> str);
Handle<String> LookupAsciiSymbol(Vector<const char> str);
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 0f2a767..8a9ae9d 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -106,10 +106,13 @@
//
#define FLAG FLAG_FULL
-// Flags for experimental language features.
+// Flags for language modes and experimental language features.
+DEFINE_bool(use_strict, false, "enforce strict mode")
+
DEFINE_bool(harmony_typeof, false, "enable harmony semantics for typeof")
DEFINE_bool(harmony_scoping, false, "enable harmony block scoping")
-DEFINE_bool(harmony_modules, false, "enable harmony modules")
+DEFINE_bool(harmony_modules, false,
+ "enable harmony modules (implies block scoping)")
DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
DEFINE_bool(harmony_collections, false,
"enable harmony collections (sets, maps, and weak maps)")
@@ -118,9 +121,10 @@
DEFINE_implication(harmony, harmony_modules)
DEFINE_implication(harmony, harmony_proxies)
DEFINE_implication(harmony, harmony_collections)
+DEFINE_implication(harmony_modules, harmony_scoping)
// Flags for experimental implementation features.
-DEFINE_bool(smi_only_arrays, false, "tracks arrays with only smi values")
+DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values")
DEFINE_bool(clever_optimizations,
true,
"Optimize object size, Array shift, DOM strings and string +")
@@ -177,12 +181,17 @@
"weight back edges by jump distance for interrupt triggering")
DEFINE_int(interrupt_budget, 10000,
"execution budget before interrupt is triggered")
+DEFINE_int(type_info_threshold, 0,
+ "percentage of ICs that must have type info to allow optimization")
DEFINE_implication(experimental_profiler, watch_ic_patching)
DEFINE_implication(experimental_profiler, self_optimization)
DEFINE_implication(experimental_profiler, count_based_interrupts)
DEFINE_implication(experimental_profiler, weighted_back_edges)
+DEFINE_bool(trace_opt_verbose, false, "extra verbose compilation tracing")
+DEFINE_implication(trace_opt_verbose, trace_opt)
+
// assembler-ia32.cc / assembler-arm.cc / assembler-x64.cc
DEFINE_bool(debug_code, false,
"generate extra code (assertions) for debugging")
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 916d52d..3d10e96 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -303,6 +303,7 @@
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
code->set_optimizable(info->IsOptimizable());
cgen.PopulateDeoptimizationData(code);
+ cgen.PopulateTypeFeedbackInfo(code);
cgen.PopulateTypeFeedbackCells(code);
code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
code->set_handler_table(*cgen.handler_table());
@@ -361,6 +362,13 @@
}
+void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
+ Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
+ info->set_ic_total_count(ic_total_count_);
+ code->set_type_feedback_info(*info);
+}
+
+
void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) {
if (type_feedback_cells_.is_empty()) return;
int length = type_feedback_cells_.length();
@@ -371,7 +379,8 @@
cache->SetAstId(i, Smi::FromInt(type_feedback_cells_[i].ast_id));
cache->SetCell(i, *type_feedback_cells_[i].cell);
}
- code->set_type_feedback_cells(*cache);
+ TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells(
+ *cache);
}
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 2733bdf..efa9391 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -89,16 +89,11 @@
? info->function()->ast_node_count() : 0),
stack_checks_(2), // There's always at least one.
type_feedback_cells_(info->HasDeoptimizationSupport()
- ? info->function()->ast_node_count() : 0) { }
+ ? info->function()->ast_node_count() : 0),
+ ic_total_count_(0) { }
static bool MakeCode(CompilationInfo* info);
- void Generate();
- void PopulateDeoptimizationData(Handle<Code> code);
- void PopulateTypeFeedbackCells(Handle<Code> code);
-
- Handle<FixedArray> handler_table() { return handler_table_; }
-
// Encode state and pc-offset as a BitField<type, start, size>.
// Only use 30 bits because we encode the result as a smi.
class StateField : public BitField<State, 0, 1> { };
@@ -516,6 +511,10 @@
// accumulator.
void EmitKeyedPropertyAssignment(Assignment* expr);
+ void CallIC(Handle<Code> code,
+ RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+ unsigned ast_id = kNoASTId);
+
void SetFunctionPosition(FunctionLiteral* fun);
void SetReturnPosition(FunctionLiteral* fun);
void SetStatementPosition(Statement* stmt);
@@ -581,6 +580,13 @@
void VisitForTypeofValue(Expression* expr);
+ void Generate();
+ void PopulateDeoptimizationData(Handle<Code> code);
+ void PopulateTypeFeedbackInfo(Handle<Code> code);
+ void PopulateTypeFeedbackCells(Handle<Code> code);
+
+ Handle<FixedArray> handler_table() { return handler_table_; }
+
struct BailoutEntry {
unsigned id;
unsigned pc_and_state;
@@ -779,6 +785,7 @@
ZoneList<BailoutEntry> bailout_entries_;
ZoneList<BailoutEntry> stack_checks_;
ZoneList<TypeFeedbackCellEntry> type_feedback_cells_;
+ int ic_total_count_;
Handle<FixedArray> handler_table_;
Handle<JSGlobalPropertyCell> profiling_counter_;
diff --git a/src/heap.cc b/src/heap.cc
index cd8a03e..fc53eb3 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1938,6 +1938,19 @@
}
+MaybeObject* Heap::AllocateTypeFeedbackInfo() {
+ TypeFeedbackInfo* info;
+ { MaybeObject* maybe_result = AllocateStruct(TYPE_FEEDBACK_INFO_TYPE);
+ if (!maybe_result->To(&info)) return maybe_result;
+ }
+ info->set_ic_total_count(0);
+ info->set_ic_with_typeinfo_count(0);
+ info->set_type_feedback_cells(TypeFeedbackCells::cast(empty_fixed_array()),
+ SKIP_WRITE_BARRIER);
+ return info;
+}
+
+
const Heap::StringTypeTable Heap::string_type_table[] = {
#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
{type, size, k##camel_name##MapRootIndex},
@@ -2221,6 +2234,12 @@
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
+ set_module_context_map(Map::cast(obj));
+
+ { MaybeObject* maybe_obj =
+ AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+ if (!maybe_obj->ToObject(&obj)) return false;
+ }
Map* global_context_map = Map::cast(obj);
global_context_map->set_visitor_id(StaticVisitorBase::kVisitGlobalContext);
set_global_context_map(global_context_map);
@@ -3361,8 +3380,7 @@
code->set_check_type(RECEIVER_MAP_CHECK);
}
code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER);
- code->set_type_feedback_cells(TypeFeedbackCells::cast(empty_fixed_array()),
- SKIP_WRITE_BARRIER);
+ code->set_type_feedback_info(undefined_value(), SKIP_WRITE_BARRIER);
code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
code->set_gc_metadata(Smi::FromInt(0));
// Allow self references to created code object by patching the handle to
@@ -5062,8 +5080,39 @@
cell_space_->Verify(&no_dirty_regions_visitor);
lo_space_->Verify();
+
+ // TODO(svenpanne) We should enable this when our fast->slow->fast-mode dance
+ // for setting accessor properties is fixed.
+ // VerifyNoAccessorPairSharing();
}
+
+void Heap::VerifyNoAccessorPairSharing() {
+ // Verification is done in 2 phases: First we mark all AccessorPairs, checking
+ // that we mark only unmarked pairs, then we clear all marks, restoring the
+ // initial state. We use the Smi tag of the AccessorPair's getter as the
+ // marking bit, because we can never see a Smi as the getter.
+ for (int phase = 0; phase < 2; phase++) {
+ HeapObjectIterator iter(map_space());
+ for (HeapObject* obj = iter.Next(); obj != NULL; obj = iter.Next()) {
+ if (obj->IsMap()) {
+ DescriptorArray* descs = Map::cast(obj)->instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (descs->GetType(i) == CALLBACKS &&
+ descs->GetValue(i)->IsAccessorPair()) {
+ AccessorPair* accessors = AccessorPair::cast(descs->GetValue(i));
+ uintptr_t before = reinterpret_cast<intptr_t>(accessors->getter());
+ uintptr_t after = (phase == 0) ?
+ ((before & ~kSmiTagMask) | kSmiTag) :
+ ((before & ~kHeapObjectTag) | kHeapObjectTag);
+ CHECK(before != after);
+ accessors->set_getter(reinterpret_cast<Object*>(after));
+ }
+ }
+ }
+ }
+ }
+}
#endif // DEBUG
diff --git a/src/heap.h b/src/heap.h
index 32bf7a8..bb5c375 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -130,6 +130,7 @@
V(Map, catch_context_map, CatchContextMap) \
V(Map, with_context_map, WithContextMap) \
V(Map, block_context_map, BlockContextMap) \
+ V(Map, module_context_map, ModuleContextMap) \
V(Map, oddball_map, OddballMap) \
V(Map, message_object_map, JSMessageObjectMap) \
V(Map, foreign_map, ForeignMap) \
@@ -640,6 +641,9 @@
// Allocates a pre-tenured empty AccessorPair.
MUST_USE_RESULT MaybeObject* AllocateAccessorPair();
+ // Allocates an empty TypeFeedbackInfo.
+ MUST_USE_RESULT MaybeObject* AllocateTypeFeedbackInfo();
+
// Clear the Instanceof cache (used when a prototype changes).
inline void ClearInstanceofCache();
@@ -1219,6 +1223,10 @@
// Verify the heap is in its normal state before or after a GC.
void Verify();
+ // Verify that AccessorPairs are not shared, i.e. make sure that they have
+ // exactly one pointer to them.
+ void VerifyNoAccessorPairSharing();
+
void OldPointerSpaceCheckStoreBuffer();
void MapSpaceCheckStoreBuffer();
void LargeObjectSpaceCheckStoreBuffer();
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index cdc3e23..43aeeed 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1841,17 +1841,18 @@
}
+HType HFastLiteral::CalculateInferredType() {
+ // TODO(mstarzinger): Be smarter, could also be JSArray here.
+ return HType::JSObject();
+}
+
+
HType HArrayLiteral::CalculateInferredType() {
return HType::JSArray();
}
-HType HObjectLiteralFast::CalculateInferredType() {
- return HType::JSObject();
-}
-
-
-HType HObjectLiteralGeneric::CalculateInferredType() {
+HType HObjectLiteral::CalculateInferredType() {
return HType::JSObject();
}
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 069642a..3c48672 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -103,6 +103,7 @@
V(Div) \
V(ElementsKind) \
V(EnterInlined) \
+ V(FastLiteral) \
V(FixedArrayBaseLength) \
V(ForceRepresentation) \
V(FunctionLiteral) \
@@ -140,8 +141,7 @@
V(LoadNamedGeneric) \
V(Mod) \
V(Mul) \
- V(ObjectLiteralFast) \
- V(ObjectLiteralGeneric) \
+ V(ObjectLiteral) \
V(OsrEntry) \
V(OuterContext) \
V(Parameter) \
@@ -4191,17 +4191,8 @@
transitioned_map_(transitioned_map) {
SetOperandAt(0, object);
SetFlag(kUseGVN);
- SetGVNFlag(kDependsOnMaps);
SetGVNFlag(kChangesElementsKind);
- if (original_map->has_fast_double_elements()) {
- SetGVNFlag(kChangesElementsPointer);
- SetGVNFlag(kDependsOnElementsPointer);
- SetGVNFlag(kDependsOnDoubleArrayElements);
- } else if (transitioned_map->has_fast_double_elements()) {
- SetGVNFlag(kChangesElementsPointer);
- SetGVNFlag(kDependsOnElementsPointer);
- SetGVNFlag(kDependsOnArrayElements);
- }
+ SetGVNFlag(kChangesElementsPointer);
set_representation(Representation::Tagged());
}
@@ -4357,6 +4348,41 @@
};
+class HFastLiteral: public HMaterializedLiteral<1> {
+ public:
+ HFastLiteral(HValue* context,
+ Handle<JSObject> boilerplate,
+ int total_size,
+ int literal_index,
+ int depth)
+ : HMaterializedLiteral<1>(literal_index, depth),
+ boilerplate_(boilerplate),
+ total_size_(total_size) {
+ SetOperandAt(0, context);
+ }
+
+ // Maximum depth and total number of elements and properties for literal
+ // graphs to be considered for fast deep-copying.
+ static const int kMaxLiteralDepth = 3;
+ static const int kMaxLiteralProperties = 8;
+
+ HValue* context() { return OperandAt(0); }
+ Handle<JSObject> boilerplate() const { return boilerplate_; }
+ int total_size() const { return total_size_; }
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::Tagged();
+ }
+ virtual HType CalculateInferredType();
+
+ DECLARE_CONCRETE_INSTRUCTION(FastLiteral)
+
+ private:
+ Handle<JSObject> boilerplate_;
+ int total_size_;
+};
+
+
class HArrayLiteral: public HMaterializedLiteral<1> {
public:
HArrayLiteral(HValue* context,
@@ -4395,49 +4421,14 @@
};
-class HObjectLiteralFast: public HMaterializedLiteral<1> {
+class HObjectLiteral: public HMaterializedLiteral<1> {
public:
- HObjectLiteralFast(HValue* context,
- Handle<JSObject> boilerplate,
- int total_size,
- int literal_index,
- int depth)
- : HMaterializedLiteral<1>(literal_index, depth),
- boilerplate_(boilerplate),
- total_size_(total_size) {
- SetOperandAt(0, context);
- }
-
- // Maximum depth and total number of properties for object literal
- // graphs to be considered for fast deep-copying.
- static const int kMaxObjectLiteralDepth = 3;
- static const int kMaxObjectLiteralProperties = 8;
-
- HValue* context() { return OperandAt(0); }
- Handle<JSObject> boilerplate() const { return boilerplate_; }
- int total_size() const { return total_size_; }
-
- virtual Representation RequiredInputRepresentation(int index) {
- return Representation::Tagged();
- }
- virtual HType CalculateInferredType();
-
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralFast)
-
- private:
- Handle<JSObject> boilerplate_;
- int total_size_;
-};
-
-
-class HObjectLiteralGeneric: public HMaterializedLiteral<1> {
- public:
- HObjectLiteralGeneric(HValue* context,
- Handle<FixedArray> constant_properties,
- bool fast_elements,
- int literal_index,
- int depth,
- bool has_function)
+ HObjectLiteral(HValue* context,
+ Handle<FixedArray> constant_properties,
+ bool fast_elements,
+ int literal_index,
+ int depth,
+ bool has_function)
: HMaterializedLiteral<1>(literal_index, depth),
constant_properties_(constant_properties),
fast_elements_(fast_elements),
@@ -4457,7 +4448,7 @@
}
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralGeneric)
+ DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
private:
Handle<FixedArray> constant_properties_;
@@ -4552,7 +4543,7 @@
// This instruction is not marked as having side effects, but
// changes the map of the input operand. Use it only when creating
// object literals.
- ASSERT(value->IsObjectLiteralGeneric() || value->IsObjectLiteralFast());
+ ASSERT(value->IsObjectLiteral() || value->IsFastLiteral());
set_representation(Representation::Tagged());
}
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index a6b60b1..c733864 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1431,7 +1431,8 @@
void ProcessLoopBlock(HBasicBlock* block,
HBasicBlock* before_loop,
GVNFlagSet loop_kills,
- GVNFlagSet* accumulated_first_time_depends);
+ GVNFlagSet* accumulated_first_time_depends,
+ GVNFlagSet* accumulated_first_time_changes);
bool AllowCodeMotion();
bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
@@ -1512,10 +1513,12 @@
side_effects.ToIntegral());
GVNFlagSet accumulated_first_time_depends;
+ GVNFlagSet accumulated_first_time_changes;
HBasicBlock* last = block->loop_information()->GetLastBackEdge();
for (int j = block->block_id(); j <= last->block_id(); ++j) {
ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects,
- &accumulated_first_time_depends);
+ &accumulated_first_time_depends,
+ &accumulated_first_time_changes);
}
}
}
@@ -1526,7 +1529,8 @@
HBasicBlock* block,
HBasicBlock* loop_header,
GVNFlagSet loop_kills,
- GVNFlagSet* accumulated_first_time_depends) {
+ GVNFlagSet* first_time_depends,
+ GVNFlagSet* first_time_changes) {
HBasicBlock* pre_header = loop_header->predecessors()->at(0);
GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n",
@@ -1544,28 +1548,47 @@
instr->gvn_flags().ToIntegral(),
depends_flags.ToIntegral());
bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
- if (!can_hoist && instr->IsTransitionElementsKind()) {
- // It's only possible to hoist one time side effects if there are no
- // dependencies on their changes from the loop header to the current
- // instruction.
- GVNFlagSet converted_changes =
- HValue::ConvertChangesToDependsFlags(instr->ChangesFlags());
- TraceGVN("Checking dependencies on one-time instruction %d (%s) "
- "converted changes 0x%X, accumulated depends 0x%X\n",
+ if (instr->IsTransitionElementsKind()) {
+ // It's possible to hoist transitions out of a loop as long as the
+ // hoisting wouldn't move the transition past a DependsOn of one of it's
+ // changes or any instructions that might change an objects map or
+ // elements contents.
+ GVNFlagSet changes = instr->ChangesFlags();
+ GVNFlagSet hoist_depends_blockers =
+ HValue::ConvertChangesToDependsFlags(changes);
+ // In addition to not hoisting transitions above other instructions that
+ // change dependencies that the transition changes, it must not be
+ // hoisted above map changes and stores to an elements backing store
+ // that the transition might change.
+ GVNFlagSet hoist_change_blockers = changes;
+ hoist_change_blockers.Add(kChangesMaps);
+ HTransitionElementsKind* trans = HTransitionElementsKind::cast(instr);
+ if (trans->original_map()->has_fast_double_elements()) {
+ hoist_change_blockers.Add(kChangesDoubleArrayElements);
+ }
+ if (trans->transitioned_map()->has_fast_double_elements()) {
+ hoist_change_blockers.Add(kChangesArrayElements);
+ }
+ TraceGVN("Checking dependencies on HTransitionElementsKind %d (%s) "
+ "hoist depends blockers 0x%X, hoist change blockers 0x%X, "
+ "accumulated depends 0x%X, accumulated changes 0x%X\n",
instr->id(),
instr->Mnemonic(),
- converted_changes.ToIntegral(),
- accumulated_first_time_depends->ToIntegral());
- // It's possible to hoist one-time side effects from the current loop
- // loop only if they dominate all of the successor blocks in the same
- // loop and there are not any instructions that have Changes/DependsOn
- // that intervene between it and the beginning of the loop header.
+ hoist_depends_blockers.ToIntegral(),
+ hoist_change_blockers.ToIntegral(),
+ first_time_depends->ToIntegral(),
+ first_time_changes->ToIntegral());
+ // It's possible to hoist transition from the current loop loop only if
+ // they dominate all of the successor blocks in the same loop and there
+ // are not any instructions that have Changes/DependsOn that intervene
+ // between it and the beginning of the loop header.
bool in_nested_loop = block != loop_header &&
((block->parent_loop_header() != loop_header) ||
block->IsLoopHeader());
can_hoist = !in_nested_loop &&
block->IsLoopSuccessorDominator() &&
- !accumulated_first_time_depends->ContainsAnyOf(converted_changes);
+ !first_time_depends->ContainsAnyOf(hoist_depends_blockers) &&
+ !first_time_changes->ContainsAnyOf(hoist_change_blockers);
}
if (can_hoist) {
@@ -1589,10 +1612,8 @@
if (!hoisted) {
// If an instruction is not hoisted, we have to account for its side
// effects when hoisting later HTransitionElementsKind instructions.
- accumulated_first_time_depends->Add(instr->DependsOnFlags());
- GVNFlagSet converted_changes =
- HValue::ConvertChangesToDependsFlags(instr->SideEffectFlags());
- accumulated_first_time_depends->Add(converted_changes);
+ first_time_depends->Add(instr->DependsOnFlags());
+ first_time_changes->Add(instr->ChangesFlags());
}
instr = next;
}
@@ -3437,19 +3458,35 @@
}
-// Determines whether the given object literal boilerplate satisfies all
-// limits to be considered for fast deep-copying and computes the total
+// Determines whether the given array or object literal boilerplate satisfies
+// all limits to be considered for fast deep-copying and computes the total
// size of all objects that are part of the graph.
-static bool IsFastObjectLiteral(Handle<JSObject> boilerplate,
- int max_depth,
- int* max_properties,
- int* total_size) {
- if (max_depth <= 0) return false;
+static bool IsFastLiteral(Handle<JSObject> boilerplate,
+ int max_depth,
+ int* max_properties,
+ int* total_size) {
+ ASSERT(max_depth >= 0 && *max_properties >= 0);
+ if (max_depth == 0) return false;
Handle<FixedArrayBase> elements(boilerplate->elements());
if (elements->length() > 0 &&
- elements->map() != HEAP->fixed_cow_array_map()) {
- return false;
+ elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) {
+ if (!boilerplate->HasFastElements()) return false;
+ int length = elements->length();
+ for (int i = 0; i < length; i++) {
+ if ((*max_properties)-- == 0) return false;
+ Handle<Object> value = JSObject::GetElement(boilerplate, i);
+ if (value->IsJSObject()) {
+ Handle<JSObject> value_object = Handle<JSObject>::cast(value);
+ if (!IsFastLiteral(value_object,
+ max_depth - 1,
+ max_properties,
+ total_size)) {
+ return false;
+ }
+ }
+ }
+ *total_size += FixedArray::SizeFor(length);
}
Handle<FixedArray> properties(boilerplate->properties());
@@ -3458,14 +3495,14 @@
} else {
int nof = boilerplate->map()->inobject_properties();
for (int i = 0; i < nof; i++) {
- if ((*max_properties)-- <= 0) return false;
+ if ((*max_properties)-- == 0) return false;
Handle<Object> value(boilerplate->InObjectPropertyAt(i));
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
- if (!IsFastObjectLiteral(value_object,
- max_depth - 1,
- max_properties,
- total_size)) {
+ if (!IsFastLiteral(value_object,
+ max_depth - 1,
+ max_properties,
+ total_size)) {
return false;
}
}
@@ -3487,26 +3524,26 @@
// Check whether to use fast or slow deep-copying for boilerplate.
int total_size = 0;
- int max_properties = HObjectLiteralFast::kMaxObjectLiteralProperties;
+ int max_properties = HFastLiteral::kMaxLiteralProperties;
Handle<Object> boilerplate(closure->literals()->get(expr->literal_index()));
if (boilerplate->IsJSObject() &&
- IsFastObjectLiteral(Handle<JSObject>::cast(boilerplate),
- HObjectLiteralFast::kMaxObjectLiteralDepth,
- &max_properties,
- &total_size)) {
+ IsFastLiteral(Handle<JSObject>::cast(boilerplate),
+ HFastLiteral::kMaxLiteralDepth,
+ &max_properties,
+ &total_size)) {
Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate);
- literal = new(zone()) HObjectLiteralFast(context,
- boilerplate_object,
- total_size,
- expr->literal_index(),
- expr->depth());
+ literal = new(zone()) HFastLiteral(context,
+ boilerplate_object,
+ total_size,
+ expr->literal_index(),
+ expr->depth());
} else {
- literal = new(zone()) HObjectLiteralGeneric(context,
- expr->constant_properties(),
- expr->fast_elements(),
- expr->literal_index(),
- expr->depth(),
- expr->has_function());
+ literal = new(zone()) HObjectLiteral(context,
+ expr->constant_properties(),
+ expr->fast_elements(),
+ expr->literal_index(),
+ expr->depth(),
+ expr->has_function());
}
// The object is expected in the bailout environment during computation
@@ -3577,6 +3614,7 @@
ZoneList<Expression*>* subexprs = expr->values();
int length = subexprs->length();
HValue* context = environment()->LookupContext();
+ HInstruction* literal;
Handle<FixedArray> literals(environment()->closure()->literals());
Handle<Object> raw_boilerplate(literals->get(expr->literal_index()));
@@ -3598,12 +3636,25 @@
ElementsKind boilerplate_elements_kind =
Handle<JSObject>::cast(boilerplate)->GetElementsKind();
- HArrayLiteral* literal = new(zone()) HArrayLiteral(
- context,
- boilerplate,
- length,
- expr->literal_index(),
- expr->depth());
+ // Check whether to use fast or slow deep-copying for boilerplate.
+ int total_size = 0;
+ int max_properties = HFastLiteral::kMaxLiteralProperties;
+ if (IsFastLiteral(boilerplate,
+ HFastLiteral::kMaxLiteralDepth,
+ &max_properties,
+ &total_size)) {
+ literal = new(zone()) HFastLiteral(context,
+ boilerplate,
+ total_size,
+ expr->literal_index(),
+ expr->depth());
+ } else {
+ literal = new(zone()) HArrayLiteral(context,
+ boilerplate,
+ length,
+ expr->literal_index(),
+ expr->depth());
+ }
// The array is expected in the bailout environment during computation
// of the property values and is the value of the entire expression.
@@ -4454,7 +4505,7 @@
Handle<Map> map = maps->at(i);
ASSERT(map->IsMap());
if (!transition_target.at(i).is_null()) {
- object = AddInstruction(new(zone()) HTransitionElementsKind(
+ AddInstruction(new(zone()) HTransitionElementsKind(
object, map, transition_target.at(i)));
} else {
type_todo[map->elements_kind()] = true;
@@ -5310,33 +5361,44 @@
AddCheckConstantFunction(expr, receiver, receiver_map, true);
HValue* right = Pop();
HValue* left = Pop();
- // Do not inline if the return representation is not certain.
- if (!left->representation().Equals(right->representation())) {
- Push(left);
- Push(right);
- return false;
- }
-
Pop(); // Pop receiver.
- Token::Value op = (id == kMathMin) ? Token::LT : Token::GT;
- HCompareIDAndBranch* compare = NULL;
- if (left->representation().IsTagged()) {
- HChange* left_cvt =
- new(zone()) HChange(left, Representation::Double(), false, true);
- left_cvt->SetFlag(HValue::kBailoutOnMinusZero);
- AddInstruction(left_cvt);
- HChange* right_cvt =
- new(zone()) HChange(right, Representation::Double(), false, true);
- right_cvt->SetFlag(HValue::kBailoutOnMinusZero);
- AddInstruction(right_cvt);
- compare = new(zone()) HCompareIDAndBranch(left_cvt, right_cvt, op);
- compare->SetInputRepresentation(Representation::Double());
- } else {
- compare = new(zone()) HCompareIDAndBranch(left, right, op);
- compare->SetInputRepresentation(left->representation());
+ HValue* left_operand = left;
+ HValue* right_operand = right;
+
+ // If we do not have two integers, we convert to double for comparison.
+ if (!left->representation().IsInteger32() ||
+ !right->representation().IsInteger32()) {
+ if (!left->representation().IsDouble()) {
+ HChange* left_convert = new(zone()) HChange(
+ left,
+ Representation::Double(),
+ false, // Do not truncate when converting to double.
+ true); // Deoptimize for undefined.
+ left_convert->SetFlag(HValue::kBailoutOnMinusZero);
+ left_operand = AddInstruction(left_convert);
+ }
+ if (!right->representation().IsDouble()) {
+ HChange* right_convert = new(zone()) HChange(
+ right,
+ Representation::Double(),
+ false, // Do not truncate when converting to double.
+ true); // Deoptimize for undefined.
+ right_convert->SetFlag(HValue::kBailoutOnMinusZero);
+ right_operand = AddInstruction(right_convert);
+ }
}
+ ASSERT(left_operand->representation().Equals(
+ right_operand->representation()));
+ ASSERT(!left_operand->representation().IsTagged());
+
+ Token::Value op = (id == kMathMin) ? Token::LT : Token::GT;
+
+ HCompareIDAndBranch* compare =
+ new(zone()) HCompareIDAndBranch(left_operand, right_operand, op);
+ compare->SetInputRepresentation(left_operand->representation());
+
HBasicBlock* return_left = graph()->CreateBasicBlock();
HBasicBlock* return_right = graph()->CreateBasicBlock();
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 857622d..06c1e8e 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -876,7 +876,7 @@
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
- __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
+ CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
patch_site.EmitPatchInfo();
__ test(eax, eax);
__ j(not_equal, &next_test);
@@ -1189,7 +1189,7 @@
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
- __ call(ic, mode);
+ CallIC(ic, mode);
}
@@ -1270,7 +1270,7 @@
__ mov(eax, GlobalObjectOperand());
__ mov(ecx, var->name());
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
context()->Plug(eax);
break;
}
@@ -1470,7 +1470,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- __ call(ic, RelocInfo::CODE_TARGET, key->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, key->id());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
VisitForEffect(value);
@@ -1734,14 +1734,14 @@
ASSERT(!key->handle()->IsSmi());
__ mov(ecx, Immediate(key->handle()));
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- __ call(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
}
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
- __ call(ic, RelocInfo::CODE_TARGET, prop->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
}
@@ -1762,7 +1762,7 @@
__ bind(&stub_call);
__ mov(eax, ecx);
BinaryOpStub stub(op, mode);
- __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
@@ -1847,7 +1847,7 @@
__ pop(edx);
BinaryOpStub stub(op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
context()->Plug(eax);
}
@@ -1888,7 +1888,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- __ call(ic);
+ CallIC(ic);
break;
}
case KEYED_PROPERTY: {
@@ -1901,7 +1901,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- __ call(ic);
+ CallIC(ic);
break;
}
}
@@ -1919,7 +1919,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
} else if (op == Token::INIT_CONST) {
// Const initializers need a write barrier.
@@ -2028,7 +2028,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
// If the assignment ends an initialization block, revert to fast case.
if (expr->ends_initialization_block()) {
@@ -2068,7 +2068,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
// If the assignment ends an initialization block, revert to fast case.
if (expr->ends_initialization_block()) {
@@ -2102,6 +2102,16 @@
}
+void FullCodeGenerator::CallIC(Handle<Code> code,
+ RelocInfo::Mode rmode,
+ unsigned ast_id) {
+ ic_total_count_++;
+ __ call(code, rmode, ast_id);
+}
+
+
+
+
void FullCodeGenerator::EmitCallWithIC(Call* expr,
Handle<Object> name,
RelocInfo::Mode mode) {
@@ -2118,7 +2128,7 @@
SetSourcePosition(expr->position());
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- __ call(ic, mode, expr->id());
+ CallIC(ic, mode, expr->id());
RecordJSReturnSite(expr);
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2150,7 +2160,7 @@
Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
__ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
- __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
RecordJSReturnSite(expr);
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -3737,7 +3747,7 @@
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
- __ call(ic, mode, expr->id());
+ CallIC(ic, mode, expr->id());
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
} else {
@@ -3895,7 +3905,7 @@
// accumulator register eax.
VisitForAccumulatorValue(expr->expression());
SetSourcePosition(expr->position());
- __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
context()->Plug(eax);
}
@@ -4015,7 +4025,7 @@
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
- __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+ CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4049,7 +4059,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->StoreIC_Initialize()
: isolate()->builtins()->StoreIC_Initialize_Strict();
- __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
if (!context()->IsEffect()) {
@@ -4066,7 +4076,7 @@
Handle<Code> ic = is_classic_mode()
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
- __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
// Result is on the stack
@@ -4094,7 +4104,7 @@
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
// Use a regular load, not a contextual load, to avoid a reference
// error.
- __ call(ic);
+ CallIC(ic);
PrepareForBailout(expr, TOS_REG);
context()->Plug(eax);
} else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
@@ -4274,7 +4284,7 @@
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CompareIC::GetUninitialized(op);
- __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+ CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
patch_site.EmitPatchInfo();
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 538645a..3f00354 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4259,26 +4259,35 @@
__ Assert(equal, "Unexpected object literal boilerplate");
}
+ // Only elements backing stores for non-COW arrays need to be copied.
+ Handle<FixedArrayBase> elements(object->elements());
+ bool has_elements = elements->length() > 0 &&
+ elements->map() != isolate()->heap()->fixed_cow_array_map();
+
// Increase the offset so that subsequent objects end up right after
- // this one.
- int current_offset = *offset;
- int size = object->map()->instance_size();
- *offset += size;
+ // this object and its backing store.
+ int object_offset = *offset;
+ int object_size = object->map()->instance_size();
+ int elements_offset = *offset + object_size;
+ int elements_size = has_elements ? elements->Size() : 0;
+ *offset += object_size + elements_size;
// Copy object header.
ASSERT(object->properties()->length() == 0);
- ASSERT(object->elements()->length() == 0 ||
- object->elements()->map() == isolate()->heap()->fixed_cow_array_map());
int inobject_properties = object->map()->inobject_properties();
- int header_size = size - inobject_properties * kPointerSize;
+ int header_size = object_size - inobject_properties * kPointerSize;
for (int i = 0; i < header_size; i += kPointerSize) {
- __ mov(ecx, FieldOperand(source, i));
- __ mov(FieldOperand(result, current_offset + i), ecx);
+ if (has_elements && i == JSObject::kElementsOffset) {
+ __ lea(ecx, Operand(result, elements_offset));
+ } else {
+ __ mov(ecx, FieldOperand(source, i));
+ }
+ __ mov(FieldOperand(result, object_offset + i), ecx);
}
// Copy in-object properties.
for (int i = 0; i < inobject_properties; i++) {
- int total_offset = current_offset + object->GetInObjectPropertyOffset(i);
+ int total_offset = object_offset + object->GetInObjectPropertyOffset(i);
Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i));
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
@@ -4293,10 +4302,40 @@
__ mov(FieldOperand(result, total_offset), Immediate(value));
}
}
+
+ // Copy elements backing store header.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ if (has_elements) {
+ __ LoadHeapObject(source, elements);
+ for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) {
+ __ mov(ecx, FieldOperand(source, i));
+ __ mov(FieldOperand(result, elements_offset + i), ecx);
+ }
+ }
+
+ // Copy elements backing store content.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ int elements_length = has_elements ? elements->length() : 0;
+ for (int i = 0; i < elements_length; i++) {
+ int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
+ Handle<Object> value = JSObject::GetElement(object, i);
+ if (value->IsJSObject()) {
+ Handle<JSObject> value_object = Handle<JSObject>::cast(value);
+ __ lea(ecx, Operand(result, *offset));
+ __ mov(FieldOperand(result, total_offset), ecx);
+ __ LoadHeapObject(source, value_object);
+ EmitDeepCopy(value_object, result, source, offset);
+ } else if (value->IsHeapObject()) {
+ __ LoadHeapObject(ecx, Handle<HeapObject>::cast(value));
+ __ mov(FieldOperand(result, total_offset), ecx);
+ } else {
+ __ mov(FieldOperand(result, total_offset), Immediate(value));
+ }
+ }
}
-void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) {
+void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
int size = instr->hydrogen()->total_size();
@@ -4318,7 +4357,7 @@
}
-void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
+void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
Handle<FixedArray> literals(instr->environment()->closure()->literals());
Handle<FixedArray> constant_properties =
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index b2d1b36..abf2f02 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -2212,6 +2212,13 @@
}
+LInstruction* LChunkBuilder::DoFastLiteral(HFastLiteral* instr) {
+ LOperand* context = UseFixed(instr->context(), esi);
+ return MarkAsCall(
+ DefineFixed(new(zone()) LFastLiteral(context), eax), instr);
+}
+
+
LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
LOperand* context = UseFixed(instr->context(), esi);
return MarkAsCall(
@@ -2219,18 +2226,10 @@
}
-LInstruction* LChunkBuilder::DoObjectLiteralFast(HObjectLiteralFast* instr) {
+LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
LOperand* context = UseFixed(instr->context(), esi);
return MarkAsCall(
- DefineFixed(new(zone()) LObjectLiteralFast(context), eax), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoObjectLiteralGeneric(
- HObjectLiteralGeneric* instr) {
- LOperand* context = UseFixed(instr->context(), esi);
- return MarkAsCall(
- DefineFixed(new(zone()) LObjectLiteralGeneric(context), eax), instr);
+ DefineFixed(new(zone()) LObjectLiteral(context), eax), instr);
}
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index fb24754..a8da5f6 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -87,6 +87,7 @@
V(DivI) \
V(DoubleToI) \
V(ElementsKind) \
+ V(FastLiteral) \
V(FixedArrayBaseLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
@@ -130,8 +131,7 @@
V(NumberTagD) \
V(NumberTagI) \
V(NumberUntagD) \
- V(ObjectLiteralFast) \
- V(ObjectLiteralGeneric) \
+ V(ObjectLiteral) \
V(OsrEntry) \
V(OuterContext) \
V(Parameter) \
@@ -1991,6 +1991,19 @@
};
+class LFastLiteral: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LFastLiteral(LOperand* context) {
+ inputs_[0] = context;
+ }
+
+ LOperand* context() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(FastLiteral, "fast-literal")
+ DECLARE_HYDROGEN_ACCESSOR(FastLiteral)
+};
+
+
class LArrayLiteral: public LTemplateInstruction<1, 1, 0> {
public:
explicit LArrayLiteral(LOperand* context) {
@@ -2004,29 +2017,16 @@
};
-class LObjectLiteralFast: public LTemplateInstruction<1, 1, 0> {
+class LObjectLiteral: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LObjectLiteralFast(LOperand* context) {
+ explicit LObjectLiteral(LOperand* context) {
inputs_[0] = context;
}
LOperand* context() { return inputs_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralFast, "object-literal-fast")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralFast)
-};
-
-
-class LObjectLiteralGeneric: public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LObjectLiteralGeneric(LOperand* context) {
- inputs_[0] = context;
- }
-
- LOperand* context() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralGeneric, "object-literal-generic")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralGeneric)
+ DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
+ DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
};
diff --git a/src/ic-inl.h b/src/ic-inl.h
index 7467881..6a86921 100644
--- a/src/ic-inl.h
+++ b/src/ic-inl.h
@@ -79,10 +79,10 @@
void IC::SetTargetAtAddress(Address address, Code* target) {
ASSERT(target->is_inline_cache_stub() || target->is_compare_ic_stub());
+ Code* old_target = GetTargetAtAddress(address);
#ifdef DEBUG
// STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark
// ICs as strict mode. The strict-ness of the IC must be preserved.
- Code* old_target = GetTargetAtAddress(address);
if (old_target->kind() == Code::STORE_IC ||
old_target->kind() == Code::KEYED_STORE_IC) {
ASSERT(Code::GetStrictMode(old_target->extra_ic_state()) ==
@@ -92,7 +92,7 @@
Assembler::set_target_address_at(address, target->instruction_start());
target->GetHeap()->incremental_marking()->RecordCodeTargetPatch(address,
target);
- PostPatching();
+ PostPatching(address, target, old_target);
}
diff --git a/src/ic.cc b/src/ic.cc
index f774b92..642a9e2 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -296,7 +296,32 @@
}
-void IC::PostPatching() {
+void IC::PostPatching(Address address, Code* target, Code* old_target) {
+ if (FLAG_type_info_threshold > 0) {
+ if (old_target->is_inline_cache_stub() &&
+ target->is_inline_cache_stub()) {
+ State old_state = old_target->ic_state();
+ State new_state = target->ic_state();
+ bool was_uninitialized =
+ old_state == UNINITIALIZED || old_state == PREMONOMORPHIC;
+ bool is_uninitialized =
+ new_state == UNINITIALIZED || new_state == PREMONOMORPHIC;
+ int delta = 0;
+ if (was_uninitialized && !is_uninitialized) {
+ delta = 1;
+ } else if (!was_uninitialized && is_uninitialized) {
+ delta = -1;
+ }
+ if (delta != 0) {
+ Code* host = target->GetHeap()->isolate()->
+ inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
+ TypeFeedbackInfo* info =
+ TypeFeedbackInfo::cast(host->type_feedback_info());
+ info->set_ic_with_typeinfo_count(
+ info->ic_with_typeinfo_count() + delta);
+ }
+ }
+ }
if (FLAG_watch_ic_patching) {
Isolate::Current()->runtime_profiler()->NotifyICChanged();
// We do not want to optimize until the ICs have settled down,
@@ -313,7 +338,9 @@
if (raw_frame->is_java_script()) {
JSFunction* function =
JSFunction::cast(JavaScriptFrame::cast(raw_frame)->function());
- function->shared()->set_profiler_ticks(0);
+ if (function->IsOptimized()) continue;
+ SharedFunctionInfo* shared = function->shared();
+ shared->set_profiler_ticks(0);
}
it.Advance();
}
diff --git a/src/ic.h b/src/ic.h
index 5711a48..5662552 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -165,7 +165,7 @@
// Access the target code for the given IC address.
static inline Code* GetTargetAtAddress(Address address);
static inline void SetTargetAtAddress(Address address, Code* target);
- static void PostPatching();
+ static void PostPatching(Address address, Code* target, Code* old_target);
private:
// Frame pointer for the frame that uses (calls) the IC.
diff --git a/src/isolate.cc b/src/isolate.cc
index 96c45b1..128136f 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -775,10 +775,12 @@
HandleScope scope;
Handle<JSObject> receiver_handle(receiver);
Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
- thread_local_top()->failed_access_check_callback_(
- v8::Utils::ToLocal(receiver_handle),
- type,
- v8::Utils::ToLocal(data));
+ { VMState state(this, EXTERNAL);
+ thread_local_top()->failed_access_check_callback_(
+ v8::Utils::ToLocal(receiver_handle),
+ type,
+ v8::Utils::ToLocal(data));
+ }
}
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 18b86ba..82b4958 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -3597,22 +3597,20 @@
// -------------------------------------------------------------------
// Tree to graph conversion
-static const int kSpaceRangeCount = 20;
-static const int kSpaceRangeAsciiCount = 4;
-static const uc16 kSpaceRanges[kSpaceRangeCount] = { 0x0009, 0x000D, 0x0020,
- 0x0020, 0x00A0, 0x00A0, 0x1680, 0x1680, 0x180E, 0x180E, 0x2000, 0x200A,
- 0x2028, 0x2029, 0x202F, 0x202F, 0x205F, 0x205F, 0x3000, 0x3000 };
+static const uc16 kSpaceRanges[] = { 0x0009, 0x000D, 0x0020, 0x0020, 0x00A0,
+ 0x00A0, 0x1680, 0x1680, 0x180E, 0x180E, 0x2000, 0x200A, 0x2028, 0x2029,
+ 0x202F, 0x202F, 0x205F, 0x205F, 0x3000, 0x3000, 0xFEFF, 0xFEFF };
+static const int kSpaceRangeCount = ARRAY_SIZE(kSpaceRanges);
-static const int kWordRangeCount = 8;
-static const uc16 kWordRanges[kWordRangeCount] = { '0', '9', 'A', 'Z', '_',
- '_', 'a', 'z' };
+static const uc16 kWordRanges[] = { '0', '9', 'A', 'Z', '_', '_', 'a', 'z' };
+static const int kWordRangeCount = ARRAY_SIZE(kWordRanges);
-static const int kDigitRangeCount = 2;
-static const uc16 kDigitRanges[kDigitRangeCount] = { '0', '9' };
+static const uc16 kDigitRanges[] = { '0', '9' };
+static const int kDigitRangeCount = ARRAY_SIZE(kDigitRanges);
-static const int kLineTerminatorRangeCount = 6;
-static const uc16 kLineTerminatorRanges[kLineTerminatorRangeCount] = { 0x000A,
- 0x000A, 0x000D, 0x000D, 0x2028, 0x2029 };
+static const uc16 kLineTerminatorRanges[] = { 0x000A, 0x000A, 0x000D, 0x000D,
+ 0x2028, 0x2029 };
+static const int kLineTerminatorRangeCount = ARRAY_SIZE(kLineTerminatorRanges);
RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
RegExpNode* on_success) {
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 1adb747..9d83d90 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1176,11 +1176,15 @@
Heap* heap = map->GetHeap();
Code* code = reinterpret_cast<Code*>(object);
if (FLAG_cleanup_code_caches_at_gc) {
- TypeFeedbackCells* type_feedback_cells = code->type_feedback_cells();
- for (int i = 0; i < type_feedback_cells->CellCount(); i++) {
- ASSERT(type_feedback_cells->AstId(i)->IsSmi());
- JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i);
- cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
+ Object* raw_info = code->type_feedback_info();
+ if (raw_info->IsTypeFeedbackInfo()) {
+ TypeFeedbackCells* type_feedback_cells =
+ TypeFeedbackInfo::cast(raw_info)->type_feedback_cells();
+ for (int i = 0; i < type_feedback_cells->CellCount(); i++) {
+ ASSERT(type_feedback_cells->AstId(i)->IsSmi());
+ JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i);
+ cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
+ }
}
}
code->CodeIterateBody<StaticMarkingVisitor>(heap);
diff --git a/src/math.js b/src/math.js
index f4426f4..8e735c4 100644
--- a/src/math.js
+++ b/src/math.js
@@ -29,15 +29,15 @@
// Keep reference to original values of some global properties. This
// has the added benefit that the code in this file is isolated from
// changes to these properties.
-const $floor = MathFloor;
-const $random = MathRandom;
-const $abs = MathAbs;
+var $floor = MathFloor;
+var $random = MathRandom;
+var $abs = MathAbs;
// Instance class name can only be set on functions. That is the only
// purpose for MathConstructor.
function MathConstructor() {}
%FunctionSetInstanceClassName(MathConstructor, 'Math');
-const $Math = new MathConstructor();
+var $Math = new MathConstructor();
$Math.__proto__ = $Object.prototype;
%SetProperty(global, "Math", $Math, DONT_ENUM);
diff --git a/src/messages.js b/src/messages.js
index cd4add4..e641133 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -25,17 +25,16 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
// -------------------------------------------------------------------
//
// If this object gets passed to an error constructor the error will
// get an accessor for .message that constructs a descriptive error
// message on access.
-const kAddMessageAccessorsMarker = { };
+var kAddMessageAccessorsMarker = { };
// This will be lazily initialized when first needed (and forcibly
// overwritten even though it's const).
-const kMessages = 0;
+var kMessages = 0;
function FormatString(format, message) {
var args = %MessageGetArguments(message);
@@ -603,7 +602,7 @@
this.end = end;
}
-const kLineLengthLimit = 78;
+var kLineLengthLimit = 78;
/**
* Restrict source location start and end positions to make the source slice
@@ -748,18 +747,18 @@
// can't rely on 'this' being the same as 'obj'.
var hasBeenSet = false;
var value;
- function getter() {
+ var getter = function() {
if (hasBeenSet) {
return value;
}
hasBeenSet = true;
value = fun(obj);
return value;
- }
- function setter(v) {
+ };
+ var setter = function(v) {
hasBeenSet = true;
value = v;
- }
+ };
%DefineOrRedefineAccessorProperty(obj, name, GETTER, getter, DONT_ENUM);
%DefineOrRedefineAccessorProperty(obj, name, SETTER, setter, DONT_ENUM);
}
@@ -1090,7 +1089,7 @@
function SetUpError() {
// Define special error type constructors.
- function DefineError(f) {
+ var DefineError = function(f) {
// Store the error function in both the global object
// and the runtime object. The function is fetched
// from the runtime object when throwing errors from
@@ -1106,7 +1105,7 @@
// However, it can't be an instance of the Error object because
// it hasn't been properly configured yet. Instead we create a
// special not-a-true-error-but-close-enough object.
- function ErrorPrototype() {}
+ var ErrorPrototype = function() {};
%FunctionSetPrototype(ErrorPrototype, $Object.prototype);
%FunctionSetInstanceClassName(ErrorPrototype, 'Error');
%FunctionSetPrototype(f, new ErrorPrototype());
@@ -1148,7 +1147,7 @@
}
});
%SetNativeFlag(f);
- }
+ };
DefineError(function Error() { });
DefineError(function TypeError() { });
@@ -1167,8 +1166,8 @@
// Global list of error objects visited during ErrorToString. This is
// used to detect cycles in error toString formatting.
-const visited_errors = new InternalArray();
-const cyclic_error_marker = new $Object();
+var visited_errors = new InternalArray();
+var cyclic_error_marker = new $Object();
function ErrorToStringDetectCycle(error) {
if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
@@ -1213,4 +1212,4 @@
// Boilerplate for exceptions for stack overflows. Used from
// Isolate::StackOverflow().
-const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []);
+var kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []);
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 9f66e78..4527935 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -133,10 +133,8 @@
//
// The function builds a JS frame. Please see JavaScriptFrameConstants in
// frames-mips.h for its layout.
-void FullCodeGenerator::Generate(CompilationInfo* info) {
- ASSERT(info_ == NULL);
- info_ = info;
- scope_ = info->scope();
+void FullCodeGenerator::Generate() {
+ CompilationInfo* info = info_;
handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
SetFunctionPosition(function());
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 34e1a82..252e8f4 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -2764,6 +2764,15 @@
}
+void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
+ __ LoadHeapObject(scratch0(), instr->hydrogen()->pairs());
+ __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
+ // The context is the first argument.
+ __ Push(cp, scratch0(), scratch1());
+ CallRuntime(Runtime::kDeclareGlobals, 3, instr);
+}
+
+
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
Register context = ToRegister(instr->context());
Register result = ToRegister(instr->result());
@@ -4272,26 +4281,35 @@
ASSERT(!source.is(a2));
ASSERT(!result.is(a2));
+ // Only elements backing stores for non-COW arrays need to be copied.
+ Handle<FixedArrayBase> elements(object->elements());
+ bool has_elements = elements->length() > 0 &&
+ elements->map() != isolate()->heap()->fixed_cow_array_map();
+
// Increase the offset so that subsequent objects end up right after
- // this one.
- int current_offset = *offset;
- int size = object->map()->instance_size();
- *offset += size;
+ // this object and its backing store.
+ int object_offset = *offset;
+ int object_size = object->map()->instance_size();
+ int elements_offset = *offset + object_size;
+ int elements_size = has_elements ? elements->Size() : 0;
+ *offset += object_size + elements_size;
// Copy object header.
ASSERT(object->properties()->length() == 0);
- ASSERT(object->elements()->length() == 0 ||
- object->elements()->map() == isolate()->heap()->fixed_cow_array_map());
int inobject_properties = object->map()->inobject_properties();
- int header_size = size - inobject_properties * kPointerSize;
+ int header_size = object_size - inobject_properties * kPointerSize;
for (int i = 0; i < header_size; i += kPointerSize) {
- __ lw(a2, FieldMemOperand(source, i));
- __ sw(a2, FieldMemOperand(result, current_offset + i));
+ if (has_elements && i == JSObject::kElementsOffset) {
+ __ Addu(a2, result, Operand(elements_offset));
+ } else {
+ __ lw(a2, FieldMemOperand(source, i));
+ }
+ __ sw(a2, FieldMemOperand(result, object_offset + i));
}
// Copy in-object properties.
for (int i = 0; i < inobject_properties; i++) {
- int total_offset = current_offset + object->GetInObjectPropertyOffset(i);
+ int total_offset = object_offset + object->GetInObjectPropertyOffset(i);
Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i));
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
@@ -4307,10 +4325,42 @@
__ sw(a2, FieldMemOperand(result, total_offset));
}
}
+
+
+ // Copy elements backing store header.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ if (has_elements) {
+ __ LoadHeapObject(source, elements);
+ for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) {
+ __ lw(a2, FieldMemOperand(source, i));
+ __ sw(a2, FieldMemOperand(result, elements_offset + i));
+ }
+ }
+
+ // Copy elements backing store content.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ int elements_length = has_elements ? elements->length() : 0;
+ for (int i = 0; i < elements_length; i++) {
+ int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
+ Handle<Object> value = JSObject::GetElement(object, i);
+ if (value->IsJSObject()) {
+ Handle<JSObject> value_object = Handle<JSObject>::cast(value);
+ __ Addu(a2, result, Operand(*offset));
+ __ sw(a2, FieldMemOperand(result, total_offset));
+ __ LoadHeapObject(source, value_object);
+ EmitDeepCopy(value_object, result, source, offset);
+ } else if (value->IsHeapObject()) {
+ __ LoadHeapObject(a2, Handle<HeapObject>::cast(value));
+ __ sw(a2, FieldMemOperand(result, total_offset));
+ } else {
+ __ li(a2, Operand(value));
+ __ sw(a2, FieldMemOperand(result, total_offset));
+ }
+ }
}
-void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) {
+void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
int size = instr->hydrogen()->total_size();
// Allocate all objects that are part of the literal in one big
@@ -4332,7 +4382,7 @@
}
-void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
+void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
Handle<FixedArray> literals(instr->environment()->closure()->literals());
Handle<FixedArray> constant_properties =
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 0bc2223..c534abc 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -1124,6 +1124,11 @@
}
+LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
+ return MarkAsCall(new LDeclareGlobals, instr);
+}
+
+
LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
return DefineAsRegister(new LGlobalObject(context));
@@ -2093,19 +2098,18 @@
}
+LInstruction* LChunkBuilder::DoFastLiteral(HFastLiteral* instr) {
+ return MarkAsCall(DefineFixed(new LFastLiteral, v0), instr);
+}
+
+
LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
return MarkAsCall(DefineFixed(new LArrayLiteral, v0), instr);
}
-LInstruction* LChunkBuilder::DoObjectLiteralFast(HObjectLiteralFast* instr) {
- return MarkAsCall(DefineFixed(new LObjectLiteralFast, v0), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoObjectLiteralGeneric(
- HObjectLiteralGeneric* instr) {
- return MarkAsCall(DefineFixed(new LObjectLiteralGeneric, v0), instr);
+LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
+ return MarkAsCall(DefineFixed(new LObjectLiteral, v0), instr);
}
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 0a21649..f4c3c21 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -87,11 +87,13 @@
V(ConstantI) \
V(ConstantT) \
V(Context) \
+ V(DeclareGlobals) \
V(DeleteProperty) \
V(Deoptimize) \
V(DivI) \
V(DoubleToI) \
V(ElementsKind) \
+ V(FastLiteral) \
V(FixedArrayBaseLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
@@ -134,8 +136,7 @@
V(NumberTagD) \
V(NumberTagI) \
V(NumberUntagD) \
- V(ObjectLiteralFast) \
- V(ObjectLiteralGeneric) \
+ V(ObjectLiteral) \
V(OsrEntry) \
V(OuterContext) \
V(Parameter) \
@@ -1346,6 +1347,13 @@
};
+class LDeclareGlobals: public LTemplateInstruction<0, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
+ DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
+};
+
+
class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
public:
explicit LGlobalObject(LOperand* context) {
@@ -1909,6 +1917,13 @@
};
+class LFastLiteral: public LTemplateInstruction<1, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(FastLiteral, "fast-literal")
+ DECLARE_HYDROGEN_ACCESSOR(FastLiteral)
+};
+
+
class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
@@ -1916,17 +1931,10 @@
};
-class LObjectLiteralFast: public LTemplateInstruction<1, 0, 0> {
+class LObjectLiteral: public LTemplateInstruction<1, 0, 0> {
public:
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralFast, "object-literal-fast")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralFast)
-};
-
-
-class LObjectLiteralGeneric: public LTemplateInstruction<1, 0, 0> {
- public:
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralGeneric, "object-literal-generic")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralGeneric)
+ DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
+ DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
};
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 0944b71..168a12d 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -144,32 +144,32 @@
// Type names of the different mirrors.
-const UNDEFINED_TYPE = 'undefined';
-const NULL_TYPE = 'null';
-const BOOLEAN_TYPE = 'boolean';
-const NUMBER_TYPE = 'number';
-const STRING_TYPE = 'string';
-const OBJECT_TYPE = 'object';
-const FUNCTION_TYPE = 'function';
-const REGEXP_TYPE = 'regexp';
-const ERROR_TYPE = 'error';
-const PROPERTY_TYPE = 'property';
-const FRAME_TYPE = 'frame';
-const SCRIPT_TYPE = 'script';
-const CONTEXT_TYPE = 'context';
-const SCOPE_TYPE = 'scope';
+var UNDEFINED_TYPE = 'undefined';
+var NULL_TYPE = 'null';
+var BOOLEAN_TYPE = 'boolean';
+var NUMBER_TYPE = 'number';
+var STRING_TYPE = 'string';
+var OBJECT_TYPE = 'object';
+var FUNCTION_TYPE = 'function';
+var REGEXP_TYPE = 'regexp';
+var ERROR_TYPE = 'error';
+var PROPERTY_TYPE = 'property';
+var FRAME_TYPE = 'frame';
+var SCRIPT_TYPE = 'script';
+var CONTEXT_TYPE = 'context';
+var SCOPE_TYPE = 'scope';
// Maximum length when sending strings through the JSON protocol.
-const kMaxProtocolStringLength = 80;
+var kMaxProtocolStringLength = 80;
// Different kind of properties.
-PropertyKind = {};
+var PropertyKind = {};
PropertyKind.Named = 1;
PropertyKind.Indexed = 2;
// A copy of the PropertyType enum from global.h
-PropertyType = {};
+var PropertyType = {};
PropertyType.Normal = 0;
PropertyType.Field = 1;
PropertyType.ConstantFunction = 2;
@@ -183,7 +183,7 @@
// Different attributes for a property.
-PropertyAttribute = {};
+var PropertyAttribute = {};
PropertyAttribute.None = NONE;
PropertyAttribute.ReadOnly = READ_ONLY;
PropertyAttribute.DontEnum = DONT_ENUM;
@@ -191,12 +191,12 @@
// A copy of the scope types from runtime.cc.
-ScopeType = { Global: 0,
- Local: 1,
- With: 2,
- Closure: 3,
- Catch: 4,
- Block: 5 };
+var ScopeType = { Global: 0,
+ Local: 1,
+ With: 2,
+ Closure: 3,
+ Catch: 4,
+ Block: 5 };
// Mirror hierarchy:
@@ -1237,24 +1237,24 @@
};
-const kFrameDetailsFrameIdIndex = 0;
-const kFrameDetailsReceiverIndex = 1;
-const kFrameDetailsFunctionIndex = 2;
-const kFrameDetailsArgumentCountIndex = 3;
-const kFrameDetailsLocalCountIndex = 4;
-const kFrameDetailsSourcePositionIndex = 5;
-const kFrameDetailsConstructCallIndex = 6;
-const kFrameDetailsAtReturnIndex = 7;
-const kFrameDetailsFlagsIndex = 8;
-const kFrameDetailsFirstDynamicIndex = 9;
+var kFrameDetailsFrameIdIndex = 0;
+var kFrameDetailsReceiverIndex = 1;
+var kFrameDetailsFunctionIndex = 2;
+var kFrameDetailsArgumentCountIndex = 3;
+var kFrameDetailsLocalCountIndex = 4;
+var kFrameDetailsSourcePositionIndex = 5;
+var kFrameDetailsConstructCallIndex = 6;
+var kFrameDetailsAtReturnIndex = 7;
+var kFrameDetailsFlagsIndex = 8;
+var kFrameDetailsFirstDynamicIndex = 9;
-const kFrameDetailsNameIndex = 0;
-const kFrameDetailsValueIndex = 1;
-const kFrameDetailsNameValueSize = 2;
+var kFrameDetailsNameIndex = 0;
+var kFrameDetailsValueIndex = 1;
+var kFrameDetailsNameValueSize = 2;
-const kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
-const kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
-const kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
+var kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
+var kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
+var kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
/**
* Wrapper for the frame details information retreived from the VM. The frame
@@ -1732,8 +1732,8 @@
};
-const kScopeDetailsTypeIndex = 0;
-const kScopeDetailsObjectIndex = 1;
+var kScopeDetailsTypeIndex = 0;
+var kScopeDetailsObjectIndex = 1;
function ScopeDetails(frame, index) {
this.break_id_ = frame.break_id_;
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 628c61f..6f00997 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -326,6 +326,13 @@
}
+void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
+ VerifyObjectField(kIcTotalCountOffset);
+ VerifyObjectField(kIcWithTypeinfoCountOffset);
+ VerifyHeapPointer(type_feedback_cells());
+}
+
+
void FixedArray::FixedArrayVerify() {
for (int i = 0; i < length(); i++) {
Object* e = get(i);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index ee17363..326c088 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -3938,13 +3938,17 @@
Map* new_double_map = NULL;
if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
- initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, new_double_map);
+ maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
+ new_double_map);
+ if (maybe_map->IsFailure()) return maybe_map;
maybe_map = new_double_map->CopyDropTransitions();
Map* new_object_map = NULL;
if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
new_object_map->set_elements_kind(FAST_ELEMENTS);
- new_double_map->AddElementsTransition(FAST_ELEMENTS, new_object_map);
+ maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
+ new_object_map);
+ if (maybe_map->IsFailure()) return maybe_map;
global_context->set_smi_js_array_map(initial_map);
global_context->set_double_js_array_map(new_double_map);
@@ -4119,8 +4123,7 @@
ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
-ACCESSORS(Code, type_feedback_cells, TypeFeedbackCells,
- kTypeFeedbackCellsOffset)
+ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
@@ -4796,6 +4799,13 @@
}
+SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
+SMI_ACCESSORS(TypeFeedbackInfo, ic_with_typeinfo_count,
+ kIcWithTypeinfoCountOffset)
+ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
+ kTypeFeedbackCellsOffset)
+
+
Relocatable::Relocatable(Isolate* isolate) {
ASSERT(isolate == Isolate::Current());
isolate_ = isolate;
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 67adad6..d6e8920 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -554,6 +554,15 @@
}
+void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) {
+ HeapObject::PrintHeader(out, "TypeFeedbackInfo");
+ PrintF(out, "\n - ic_total_count: %d, ic_with_typeinfo_count: %d",
+ ic_total_count(), ic_with_typeinfo_count());
+ PrintF(out, "\n - type_feedback_cells: ");
+ type_feedback_cells()->FixedArrayPrint(out);
+}
+
+
void FixedArray::FixedArrayPrint(FILE* out) {
HeapObject::PrintHeader(out, "FixedArray");
PrintF(out, " - length: %d", length());
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
index 880b44b..627d1bc 100644
--- a/src/objects-visiting-inl.h
+++ b/src/objects-visiting-inl.h
@@ -109,7 +109,7 @@
IteratePointer(v, kRelocationInfoOffset);
IteratePointer(v, kHandlerTableOffset);
IteratePointer(v, kDeoptimizationDataOffset);
- IteratePointer(v, kTypeFeedbackCellsOffset);
+ IteratePointer(v, kTypeFeedbackInfoOffset);
RelocIterator it(this, mode_mask);
for (; !it.done(); it.next()) {
@@ -141,7 +141,7 @@
reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset));
StaticVisitor::VisitPointer(
heap,
- reinterpret_cast<Object**>(this->address() + kTypeFeedbackCellsOffset));
+ reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset));
RelocIterator it(this, mode_mask);
for (; !it.done(); it.next()) {
diff --git a/src/objects.cc b/src/objects.cc
index 307e825..8b44ece 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -9546,8 +9546,12 @@
return SetElementWithCallback(element, index, value, this, strict_mode);
} else {
dictionary->UpdateMaxNumberKey(index);
- // If put fails in strict mode, throw an exception.
- if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) {
+ // If a value has not been initialized we allow writing to it even if it
+ // is read-only (a declared const that has not been initialized).
+ if (!dictionary->DetailsAt(entry).IsReadOnly() ||
+ dictionary->ValueAt(entry)->IsTheHole()) {
+ dictionary->ValueAtPut(entry, value);
+ } else if (strict_mode == kStrictMode) {
Handle<Object> holder(this);
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
Handle<Object> args[2] = { number, holder };
diff --git a/src/objects.h b/src/objects.h
index 0b1c761..7068b98 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -439,7 +439,8 @@
V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info) \
V(SCRIPT, Script, script) \
V(CODE_CACHE, CodeCache, code_cache) \
- V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache)
+ V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \
+ V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info)
#ifdef ENABLE_DEBUGGER_SUPPORT
#define STRUCT_LIST_DEBUGGER(V) \
@@ -594,6 +595,7 @@
SCRIPT_TYPE,
CODE_CACHE_TYPE,
POLYMORPHIC_CODE_CACHE_TYPE,
+ TYPE_FEEDBACK_INFO_TYPE,
// The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT
// is defined. However as include/v8.h contain some of the instance type
// constants always having them avoids them getting different numbers
@@ -928,10 +930,11 @@
JSReceiver* getter);
static Handle<Object> GetElement(Handle<Object> object, uint32_t index);
- inline MaybeObject* GetElement(uint32_t index);
+ MUST_USE_RESULT inline MaybeObject* GetElement(uint32_t index);
// For use when we know that no exception can be thrown.
inline Object* GetElementNoExceptionThrown(uint32_t index);
- MaybeObject* GetElementWithReceiver(Object* receiver, uint32_t index);
+ MUST_USE_RESULT MaybeObject* GetElementWithReceiver(Object* receiver,
+ uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
Object* GetPrototype();
@@ -1011,7 +1014,8 @@
void SmiVerify();
#endif
- static const int kMinValue = (-1 << (kSmiValueSize - 1));
+ static const int kMinValue =
+ (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
static const int kMaxValue = -(kMinValue + 1);
private:
@@ -1603,22 +1607,23 @@
MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info);
// Used from Object::GetProperty().
- MaybeObject* GetPropertyWithFailedAccessCheck(
+ MUST_USE_RESULT MaybeObject* GetPropertyWithFailedAccessCheck(
Object* receiver,
LookupResult* result,
String* name,
PropertyAttributes* attributes);
- MaybeObject* GetPropertyWithInterceptor(
+ MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor(
JSReceiver* receiver,
String* name,
PropertyAttributes* attributes);
- MaybeObject* GetPropertyPostInterceptor(
+ MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor(
JSReceiver* receiver,
String* name,
PropertyAttributes* attributes);
- MaybeObject* GetLocalPropertyPostInterceptor(JSReceiver* receiver,
- String* name,
- PropertyAttributes* attributes);
+ MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
+ JSReceiver* receiver,
+ String* name,
+ PropertyAttributes* attributes);
// Returns true if this is an instance of an api function and has
// been modified since it was created. May give false positives.
@@ -1668,18 +1673,21 @@
inline void ValidateSmiOnlyElements();
// Makes sure that this object can contain HeapObject as elements.
- inline MaybeObject* EnsureCanContainHeapObjectElements();
+ MUST_USE_RESULT inline MaybeObject* EnsureCanContainHeapObjectElements();
// Makes sure that this object can contain the specified elements.
- inline MaybeObject* EnsureCanContainElements(Object** elements,
- uint32_t count,
- EnsureElementsMode mode);
- inline MaybeObject* EnsureCanContainElements(FixedArrayBase* elements,
- EnsureElementsMode mode);
- MaybeObject* EnsureCanContainElements(Arguments* arguments,
- uint32_t first_arg,
- uint32_t arg_count,
- EnsureElementsMode mode);
+ MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
+ Object** elements,
+ uint32_t count,
+ EnsureElementsMode mode);
+ MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
+ FixedArrayBase* elements,
+ EnsureElementsMode mode);
+ MUST_USE_RESULT MaybeObject* EnsureCanContainElements(
+ Arguments* arguments,
+ uint32_t first_arg,
+ uint32_t arg_count,
+ EnsureElementsMode mode);
// Do we want to keep the elements in fast case when increasing the
// capacity?
@@ -1762,7 +1770,8 @@
// Returns the index'th element.
// The undefined object if index is out of bounds.
- MaybeObject* GetElementWithInterceptor(Object* receiver, uint32_t index);
+ MUST_USE_RESULT MaybeObject* GetElementWithInterceptor(Object* receiver,
+ uint32_t index);
enum SetFastElementsCapacityMode {
kAllowSmiOnlyElements,
@@ -2069,11 +2078,12 @@
Object* structure,
uint32_t index,
Object* holder);
- MaybeObject* SetElementWithCallback(Object* structure,
- uint32_t index,
- Object* value,
- JSObject* holder,
- StrictModeFlag strict_mode);
+ MUST_USE_RESULT MaybeObject* SetElementWithCallback(
+ Object* structure,
+ uint32_t index,
+ Object* value,
+ JSObject* holder,
+ StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetElementWithInterceptor(
uint32_t index,
Object* value,
@@ -2140,9 +2150,11 @@
// If no hidden properties object has been put on this object,
// return undefined, unless create_if_absent is true, in which case
// a new dictionary is created, added to this object, and returned.
- MaybeObject* GetHiddenPropertiesDictionary(bool create_if_absent);
+ MUST_USE_RESULT MaybeObject* GetHiddenPropertiesDictionary(
+ bool create_if_absent);
// Updates the existing hidden properties dictionary.
- MaybeObject* SetHiddenPropertiesDictionary(StringDictionary* dictionary);
+ MUST_USE_RESULT MaybeObject* SetHiddenPropertiesDictionary(
+ StringDictionary* dictionary);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
};
@@ -2289,7 +2301,7 @@
// Setter and getter for elements.
inline double get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, double value);
inline void set_the_hole(int index);
@@ -2910,22 +2922,12 @@
// Returns the value at entry.
Object* ValueAt(int entry) {
- return this->get(HashTable<Shape, Key>::EntryToIndex(entry)+1);
+ return this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 1);
}
// Set the value for entry.
- // Returns false if the put wasn't performed due to property being read only.
- // Returns true on successful put.
- bool ValueAtPut(int entry, Object* value) {
- // Check that this value can actually be written.
- PropertyDetails details = DetailsAt(entry);
- // If a value has not been initilized we allow writing to it even if
- // it is read only (a declared const that has not been initialized).
- if (details.IsReadOnly() && !ValueAt(entry)->IsTheHole()) {
- return false;
- }
+ void ValueAtPut(int entry, Object* value) {
this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value);
- return true;
}
// Returns the property details for the property at entry.
@@ -3624,7 +3626,7 @@
// Setter and getter.
inline uint8_t get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, uint8_t value);
// This accessor applies the correct conversion from Smi, HeapNumber and
@@ -3653,12 +3655,12 @@
public:
// Setter and getter.
inline int8_t get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, int8_t value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalByteArray* cast(Object* obj);
@@ -3682,12 +3684,12 @@
public:
// Setter and getter.
inline uint8_t get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, uint8_t value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalUnsignedByteArray* cast(Object* obj);
@@ -3711,12 +3713,12 @@
public:
// Setter and getter.
inline int16_t get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, int16_t value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalShortArray* cast(Object* obj);
@@ -3740,12 +3742,12 @@
public:
// Setter and getter.
inline uint16_t get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, uint16_t value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalUnsignedShortArray* cast(Object* obj);
@@ -3769,12 +3771,12 @@
public:
// Setter and getter.
inline int32_t get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, int32_t value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalIntArray* cast(Object* obj);
@@ -3798,12 +3800,12 @@
public:
// Setter and getter.
inline uint32_t get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, uint32_t value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalUnsignedIntArray* cast(Object* obj);
@@ -3827,12 +3829,12 @@
public:
// Setter and getter.
inline float get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, float value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalFloatArray* cast(Object* obj);
@@ -3856,12 +3858,12 @@
public:
// Setter and getter.
inline double get_scalar(int index);
- inline MaybeObject* get(int index);
+ MUST_USE_RESULT inline MaybeObject* get(int index);
inline void set(int index, double value);
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MaybeObject* SetValue(uint32_t index, Object* value);
+ MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
// Casting.
static inline ExternalDoubleArray* cast(Object* obj);
@@ -4032,6 +4034,7 @@
// Forward declaration.
class SafepointEntry;
+class TypeFeedbackInfo;
// Code describes objects with on-the-fly generated machine code.
class Code: public HeapObject {
@@ -4103,8 +4106,9 @@
// [deoptimization_data]: Array containing data for deopt.
DECL_ACCESSORS(deoptimization_data, FixedArray)
- // [type_feedback_cells]: Array containing cache cells used for type feedback.
- DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells)
+ // [type_feedback_info]: Struct containing type feedback information.
+ // Will contain either a TypeFeedbackInfo object, or undefined.
+ DECL_ACCESSORS(type_feedback_info, Object)
// [gc_metadata]: Field used to hold GC related metadata. The contents of this
// field does not have to be traced during garbage collection since
@@ -4355,9 +4359,9 @@
static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
static const int kDeoptimizationDataOffset =
kHandlerTableOffset + kPointerSize;
- static const int kTypeFeedbackCellsOffset =
+ static const int kTypeFeedbackInfoOffset =
kDeoptimizationDataOffset + kPointerSize;
- static const int kGCMetadataOffset = kTypeFeedbackCellsOffset + kPointerSize;
+ static const int kGCMetadataOffset = kTypeFeedbackInfoOffset + kPointerSize;
static const int kFlagsOffset = kGCMetadataOffset + kPointerSize;
static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize;
@@ -4746,8 +4750,8 @@
// Adds an entry to this map's descriptor array for a transition to
// |transitioned_map| when its elements_kind is changed to |elements_kind|.
- MaybeObject* AddElementsTransition(ElementsKind elements_kind,
- Map* transitioned_map);
+ MUST_USE_RESULT MaybeObject* AddElementsTransition(
+ ElementsKind elements_kind, Map* transitioned_map);
// Returns the transitioned map for this map with the most generic
// elements_kind that's found in |candidates|, or null handle if no match is
@@ -4779,7 +4783,8 @@
Object* GetPrototypeTransition(Object* prototype);
- MaybeObject* PutPrototypeTransition(Object* prototype, Map* map);
+ MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype,
+ Map* map);
static const int kMaxPreAllocatedPropertyFields = 255;
@@ -5671,7 +5676,8 @@
// The initial map for an object created by this constructor.
inline Map* initial_map();
inline void set_initial_map(Map* value);
- inline MaybeObject* set_initial_map_and_cache_transitions(Map* value);
+ MUST_USE_RESULT inline MaybeObject* set_initial_map_and_cache_transitions(
+ Map* value);
inline bool has_initial_map();
// Get and set the prototype property on a JSFunction. If the
@@ -5682,7 +5688,7 @@
inline bool has_instance_prototype();
inline Object* prototype();
inline Object* instance_prototype();
- MaybeObject* SetInstancePrototype(Object* value);
+ MUST_USE_RESULT MaybeObject* SetInstancePrototype(Object* value);
MUST_USE_RESULT MaybeObject* SetPrototype(Object* value);
// After prototype is removed, it will not be created when accessed, and
@@ -6195,12 +6201,14 @@
LanguageMode language_mode,
int scope_position);
Object* LookupRegExp(String* source, JSRegExp::Flags flags);
- MaybeObject* Put(String* src, Object* value);
- MaybeObject* PutEval(String* src,
- Context* context,
- SharedFunctionInfo* value,
- int scope_position);
- MaybeObject* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value);
+ MUST_USE_RESULT MaybeObject* Put(String* src, Object* value);
+ MUST_USE_RESULT MaybeObject* PutEval(String* src,
+ Context* context,
+ SharedFunctionInfo* value,
+ int scope_position);
+ MUST_USE_RESULT MaybeObject* PutRegExp(String* src,
+ JSRegExp::Flags flags,
+ FixedArray* value);
// Remove given value from cache.
void Remove(Object* value);
@@ -6361,6 +6369,40 @@
};
+class TypeFeedbackInfo: public Struct {
+ public:
+ inline int ic_total_count();
+ inline void set_ic_total_count(int count);
+
+ inline int ic_with_typeinfo_count();
+ inline void set_ic_with_typeinfo_count(int count);
+
+ DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells)
+
+ static inline TypeFeedbackInfo* cast(Object* obj);
+
+#ifdef OBJECT_PRINT
+ inline void TypeFeedbackInfoPrint() {
+ TypeFeedbackInfoPrint(stdout);
+ }
+ void TypeFeedbackInfoPrint(FILE* out);
+#endif
+#ifdef DEBUG
+ void TypeFeedbackInfoVerify();
+#endif
+
+ static const int kIcTotalCountOffset = HeapObject::kHeaderSize;
+ static const int kIcWithTypeinfoCountOffset =
+ kIcTotalCountOffset + kPointerSize;
+ static const int kTypeFeedbackCellsOffset =
+ kIcWithTypeinfoCountOffset + kPointerSize;
+ static const int kSize = kTypeFeedbackCellsOffset + kPointerSize;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackInfo);
+};
+
+
enum AllowNullsFlag {ALLOW_NULLS, DISALLOW_NULLS};
enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
@@ -7665,7 +7707,7 @@
MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
// Set the content of the array to the content of storage.
- inline MaybeObject* SetContent(FixedArrayBase* storage);
+ MUST_USE_RESULT inline MaybeObject* SetContent(FixedArrayBase* storage);
// Casting.
static inline JSArray* cast(Object* obj);
diff --git a/src/parser.cc b/src/parser.cc
index 3b9b69b..3dfab29 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -654,6 +654,7 @@
return result;
}
+
FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
HistogramTimerScope timer(isolate()->counters()->parse_lazy());
@@ -1087,32 +1088,11 @@
};
-Statement* Parser::ParseSourceElement(ZoneStringList* labels,
- bool* ok) {
- // (Ecma 262 5th Edition, clause 14):
- // SourceElement:
- // Statement
- // FunctionDeclaration
- //
- // In harmony mode we allow additionally the following productions
- // SourceElement:
- // LetDeclaration
- // ConstDeclaration
-
- if (peek() == Token::FUNCTION) {
- return ParseFunctionDeclaration(ok);
- } else if (peek() == Token::LET || peek() == Token::CONST) {
- return ParseVariableStatement(kSourceElement, ok);
- }
- return ParseStatement(labels, ok);
-}
-
-
void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
int end_token,
bool* ok) {
// SourceElements ::
- // (SourceElement)* <end_token>
+ // (ModuleElement)* <end_token>
// Allocate a target stack to use for this set of source
// elements. This way, all scripts and functions get their own
@@ -1131,7 +1111,7 @@
}
Scanner::Location token_loc = scanner().peek_location();
- Statement* stat = ParseSourceElement(NULL, CHECK_OK);
+ Statement* stat = ParseModuleElement(NULL, CHECK_OK);
if (stat == NULL || stat->IsEmpty()) {
directive_prologue = false; // End of directive prologue.
continue;
@@ -1187,6 +1167,194 @@
}
+Statement* Parser::ParseModuleElement(ZoneStringList* labels,
+ bool* ok) {
+ // (Ecma 262 5th Edition, clause 14):
+ // SourceElement:
+ // Statement
+ // FunctionDeclaration
+ //
+ // In harmony mode we allow additionally the following productions
+ // ModuleElement:
+ // LetDeclaration
+ // ConstDeclaration
+ // ModuleDeclaration
+ // ImportDeclaration
+ // ExportDeclaration
+
+ switch (peek()) {
+ case Token::FUNCTION:
+ return ParseFunctionDeclaration(ok);
+ case Token::LET:
+ case Token::CONST:
+ return ParseVariableStatement(kModuleElement, ok);
+ case Token::MODULE:
+ return ParseModuleDeclaration(ok);
+ case Token::IMPORT:
+ return ParseImportDeclaration(ok);
+ case Token::EXPORT:
+ return ParseExportDeclaration(ok);
+ default:
+ return ParseStatement(labels, ok);
+ }
+}
+
+
+Block* Parser::ParseModuleDeclaration(bool* ok) {
+ // ModuleDeclaration:
+ // 'module' Identifier Module
+
+ // Create new block with one expected declaration.
+ Block* block = factory()->NewBlock(NULL, 1, true);
+ Expect(Token::MODULE, CHECK_OK);
+ Handle<String> name = ParseIdentifier(CHECK_OK);
+ // top_scope_->AddDeclaration(
+ // factory()->NewModuleDeclaration(proxy, module, top_scope_));
+ VariableProxy* proxy = Declare(name, LET, NULL, true, CHECK_OK);
+ Module* module = ParseModule(ok);
+ // TODO(rossberg): Add initialization statement to block.
+ USE(proxy);
+ USE(module);
+ return block;
+}
+
+
+Module* Parser::ParseModule(bool* ok) {
+ // Module:
+ // '{' ModuleElement '}'
+ // '=' ModulePath
+ // 'at' String
+
+ switch (peek()) {
+ case Token::LBRACE:
+ return ParseModuleLiteral(ok);
+
+ case Token::ASSIGN:
+ Expect(Token::ASSIGN, CHECK_OK);
+ return ParseModulePath(ok);
+
+ default:
+ return ParseModuleUrl(ok);
+ }
+}
+
+
+Module* Parser::ParseModuleLiteral(bool* ok) {
+ // Module:
+ // '{' ModuleElement '}'
+
+ // Construct block expecting 16 statements.
+ Block* body = factory()->NewBlock(NULL, 16, false);
+ Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
+
+ Expect(Token::LBRACE, CHECK_OK);
+ scope->set_start_position(scanner().location().beg_pos);
+ scope->SetLanguageMode(EXTENDED_MODE);
+
+ {
+ BlockState block_state(this, scope);
+ TargetCollector collector;
+ Target target(&this->target_stack_, &collector);
+ Target target_body(&this->target_stack_, body);
+ InitializationBlockFinder block_finder(top_scope_, target_stack_);
+
+ while (peek() != Token::RBRACE) {
+ Statement* stat = ParseModuleElement(NULL, CHECK_OK);
+ if (stat && !stat->IsEmpty()) {
+ body->AddStatement(stat);
+ block_finder.Update(stat);
+ }
+ }
+ }
+
+ Expect(Token::RBRACE, CHECK_OK);
+ scope->set_end_position(scanner().location().end_pos);
+ body->set_block_scope(scope);
+ return factory()->NewModuleLiteral(body);
+}
+
+
+Module* Parser::ParseModulePath(bool* ok) {
+ // ModulePath:
+ // Identifier
+ // ModulePath '.' Identifier
+
+ Module* result = ParseModuleVariable(CHECK_OK);
+
+ while (Check(Token::PERIOD)) {
+ Handle<String> name = ParseIdentifierName(CHECK_OK);
+ result = factory()->NewModulePath(result, name);
+ }
+
+ return result;
+}
+
+
+Module* Parser::ParseModuleVariable(bool* ok) {
+ // ModulePath:
+ // Identifier
+
+ Handle<String> name = ParseIdentifier(CHECK_OK);
+ VariableProxy* proxy = top_scope_->NewUnresolved(
+ factory(), name, scanner().location().beg_pos);
+ return factory()->NewModuleVariable(proxy);
+}
+
+
+Module* Parser::ParseModuleUrl(bool* ok) {
+ // Module:
+ // 'at' String
+
+ Expect(Token::IDENTIFIER, CHECK_OK);
+ Handle<String> symbol = GetSymbol(CHECK_OK);
+ if (!symbol->IsEqualTo(CStrVector("at"))) {
+ *ok = false;
+ ReportUnexpectedToken(scanner().current_token());
+ return NULL;
+ }
+ Expect(Token::STRING, CHECK_OK);
+ symbol = GetSymbol(CHECK_OK);
+
+ return factory()->NewModuleUrl(symbol);
+}
+
+
+Block* Parser::ParseImportDeclaration(bool* ok) {
+ // TODO(rossberg)
+ return NULL;
+}
+
+
+Block* Parser::ParseExportDeclaration(bool* ok) {
+ // TODO(rossberg)
+ return NULL;
+}
+
+
+Statement* Parser::ParseBlockElement(ZoneStringList* labels,
+ bool* ok) {
+ // (Ecma 262 5th Edition, clause 14):
+ // SourceElement:
+ // Statement
+ // FunctionDeclaration
+ //
+ // In harmony mode we allow additionally the following productions
+ // BlockElement (aka SourceElement):
+ // LetDeclaration
+ // ConstDeclaration
+
+ switch (peek()) {
+ case Token::FUNCTION:
+ return ParseFunctionDeclaration(ok);
+ case Token::LET:
+ case Token::CONST:
+ return ParseVariableStatement(kModuleElement, ok);
+ default:
+ return ParseStatement(labels, ok);
+ }
+}
+
+
Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
// Statement ::
// Block
@@ -1344,7 +1512,8 @@
// statically declared.
if (declaration_scope->is_function_scope() ||
declaration_scope->is_strict_or_extended_eval_scope() ||
- declaration_scope->is_block_scope()) {
+ declaration_scope->is_block_scope() ||
+ declaration_scope->is_module_scope()) {
// Declare the variable in the function scope.
var = declaration_scope->LocalLookup(name);
if (var == NULL) {
@@ -1574,10 +1743,10 @@
Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
- // The harmony mode uses source elements instead of statements.
+ // The harmony mode uses block elements instead of statements.
//
// Block ::
- // '{' SourceElement* '}'
+ // '{' BlockElement* '}'
// Construct block expecting 16 statements.
Block* body = factory()->NewBlock(labels, 16, false);
@@ -1593,7 +1762,7 @@
InitializationBlockFinder block_finder(top_scope_, target_stack_);
while (peek() != Token::RBRACE) {
- Statement* stat = ParseSourceElement(NULL, CHECK_OK);
+ Statement* stat = ParseBlockElement(NULL, CHECK_OK);
if (stat && !stat->IsEmpty()) {
body->AddStatement(stat);
block_finder.Update(stat);
@@ -1614,10 +1783,8 @@
// VariableDeclarations ';'
Handle<String> ignore;
- Block* result = ParseVariableDeclarations(var_context,
- NULL,
- &ignore,
- CHECK_OK);
+ Block* result =
+ ParseVariableDeclarations(var_context, NULL, &ignore, CHECK_OK);
ExpectSemicolon(CHECK_OK);
return result;
}
@@ -1684,8 +1851,7 @@
*ok = false;
return NULL;
case EXTENDED_MODE:
- if (var_context != kSourceElement &&
- var_context != kForStatement) {
+ if (var_context == kStatement) {
// In extended mode 'const' declarations are only allowed in source
// element positions.
ReportMessage("unprotected_const", Vector<const char*>::empty());
@@ -1710,10 +1876,8 @@
return NULL;
}
Consume(Token::LET);
- if (var_context != kSourceElement &&
- var_context != kForStatement) {
+ if (var_context == kStatement) {
// Let declarations are only allowed in source element positions.
- ASSERT(var_context == kStatement);
ReportMessage("unprotected_let", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -2453,10 +2617,7 @@
Handle<String> name;
VariableDeclarationProperties decl_props = kHasNoInitializers;
Block* variable_statement =
- ParseVariableDeclarations(kForStatement,
- &decl_props,
- &name,
- CHECK_OK);
+ ParseVariableDeclarations(kForStatement, &decl_props, &name, CHECK_OK);
bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
if (peek() == Token::IN && accept_IN) {
// Rewrite a for-in statement of the form
diff --git a/src/parser.h b/src/parser.h
index fbc4a15..66c801d 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -464,7 +464,8 @@
};
enum VariableDeclarationContext {
- kSourceElement,
+ kModuleElement,
+ kBlockElement,
kStatement,
kForStatement
};
@@ -575,7 +576,16 @@
// for failure at the call sites.
void* ParseSourceElements(ZoneList<Statement*>* processor,
int end_token, bool* ok);
- Statement* ParseSourceElement(ZoneStringList* labels, bool* ok);
+ Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
+ Block* ParseModuleDeclaration(bool* ok);
+ Module* ParseModule(bool* ok);
+ Module* ParseModuleLiteral(bool* ok);
+ Module* ParseModulePath(bool* ok);
+ Module* ParseModuleVariable(bool* ok);
+ Module* ParseModuleUrl(bool* ok);
+ Block* ParseImportDeclaration(bool* ok);
+ Block* ParseExportDeclaration(bool* ok);
+ Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
Statement* ParseStatement(ZoneStringList* labels, bool* ok);
Statement* ParseFunctionDeclaration(bool* ok);
Statement* ParseNativeDeclaration(bool* ok);
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index c27e3c9..79134da 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -365,16 +365,9 @@
Thread::Thread(const Options& options)
- : data_(new PlatformData),
- stack_size_(options.stack_size) {
- set_name(options.name);
-}
-
-
-Thread::Thread(const char* name)
- : data_(new PlatformData),
- stack_size_(0) {
- set_name(name);
+ : data_(new PlatformData()),
+ stack_size_(options.stack_size()) {
+ set_name(options.name());
}
@@ -617,8 +610,10 @@
class SamplerThread : public Thread {
public:
+ static const int kSamplerThreadStackSize = 64 * KB;
+
explicit SamplerThread(int interval)
- : Thread("SamplerThread"),
+ : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)),
interval_(interval) {}
static void AddActiveSampler(Sampler* sampler) {
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index 685e443..f3ec75a 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -84,7 +84,7 @@
void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
- PrintLiteral(node->var()->name(), false);
+ Visit(node->proxy());
}
@@ -773,7 +773,7 @@
void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
- PrintLiteralIndented("VARIABLE", node->var()->name(), false);
+ Visit(node->proxy());
}
diff --git a/src/proxy.js b/src/proxy.js
index 3cd467f..4e86c88 100644
--- a/src/proxy.js
+++ b/src/proxy.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"use strict";
+
global.Proxy = new $Object();
var $Proxy = global.Proxy
diff --git a/src/regexp.js b/src/regexp.js
index 00dd7f1..4f2eb62 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -28,7 +28,7 @@
// Expect $Object = global.Object;
// Expect $Array = global.Array;
-const $RegExp = global.RegExp;
+var $RegExp = global.RegExp;
// A recursive descent parser for Patterns according to the grammar of
// ECMA-262 15.10.1, with deviations noted below.
@@ -413,13 +413,13 @@
// The properties input, $input, and $_ are aliases for each other. When this
// value is set the value it is set to is coerced to a string.
// Getter and setter for the input.
- function RegExpGetInput() {
+ var RegExpGetInput = function() {
var regExpInput = LAST_INPUT(lastMatchInfo);
return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
- }
- function RegExpSetInput(string) {
+ };
+ var RegExpSetInput = function(string) {
LAST_INPUT(lastMatchInfo) = ToString(string);
- }
+ };
%DefineAccessor($RegExp, 'input', GETTER, RegExpGetInput, DONT_DELETE);
%DefineAccessor($RegExp, 'input', SETTER, RegExpSetInput, DONT_DELETE);
@@ -441,8 +441,8 @@
// Getter and setter for multiline.
var multiline = false;
- function RegExpGetMultiline() { return multiline; }
- function RegExpSetMultiline(flag) { multiline = flag ? true : false; }
+ var RegExpGetMultiline = function() { return multiline; };
+ var RegExpSetMultiline = function(flag) { multiline = flag ? true : false; };
%DefineAccessor($RegExp, 'multiline', GETTER, RegExpGetMultiline,
DONT_DELETE);
@@ -454,7 +454,7 @@
DONT_ENUM | DONT_DELETE);
- function NoOpSetter(ignored) {}
+ var NoOpSetter = function(ignored) {};
// Static properties set by a successful match.
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 7c24ae6..8bd59d1 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -102,6 +102,25 @@
}
+static void GetICCounts(JSFunction* function,
+ int* ic_with_typeinfo_count,
+ int* ic_total_count,
+ int* percentage) {
+ *ic_total_count = 0;
+ *ic_with_typeinfo_count = 0;
+ Object* raw_info =
+ function->shared()->code()->type_feedback_info();
+ if (raw_info->IsTypeFeedbackInfo()) {
+ TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info);
+ *ic_with_typeinfo_count = info->ic_with_typeinfo_count();
+ *ic_total_count = info->ic_total_count();
+ }
+ *percentage = *ic_total_count > 0
+ ? 100 * *ic_with_typeinfo_count / *ic_total_count
+ : 100;
+}
+
+
void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) {
ASSERT(function->IsOptimizable());
if (FLAG_trace_opt) {
@@ -109,6 +128,11 @@
function->PrintName();
PrintF(" 0x%" V8PRIxPTR, reinterpret_cast<intptr_t>(function->address()));
PrintF(" for recompilation, reason: %s", reason);
+ if (FLAG_type_info_threshold > 0) {
+ int typeinfo, total, percentage;
+ GetICCounts(function, &typeinfo, &total, &percentage);
+ PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, percentage);
+ }
PrintF("]\n");
}
@@ -258,9 +282,20 @@
int ticks = function->shared()->profiler_ticks();
if (ticks >= kProfilerTicksBeforeOptimization) {
- // If this particular function hasn't had any ICs patched for enough
- // ticks, optimize it now.
- Optimize(function, "hot and stable");
+ int typeinfo, total, percentage;
+ GetICCounts(function, &typeinfo, &total, &percentage);
+ if (percentage >= FLAG_type_info_threshold) {
+ // If this particular function hasn't had any ICs patched for enough
+ // ticks, optimize it now.
+ Optimize(function, "hot and stable");
+ } else {
+ if (FLAG_trace_opt_verbose) {
+ PrintF("[not yet optimizing ");
+ function->PrintName();
+ PrintF(", not enough type info: %d/%d (%d%%)]\n",
+ typeinfo, total, percentage);
+ }
+ }
} else if (!any_ic_changed_ &&
function->shared()->code()->instruction_size() < kMaxSizeEarlyOpt) {
// If no IC was patched since the last tick and this function is very
diff --git a/src/runtime.cc b/src/runtime.cc
index 4fc724b..15252ed 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -69,20 +69,20 @@
// Cast the given object to a value of the specified type and store
// it in a variable with the given name. If the object is not of the
// expected type call IllegalOperation and return.
-#define CONVERT_CHECKED(Type, name, obj) \
- RUNTIME_ASSERT(obj->Is##Type()); \
- Type* name = Type::cast(obj);
-
#define CONVERT_ARG_CHECKED(Type, name, index) \
RUNTIME_ASSERT(args[index]->Is##Type()); \
+ Type* name = Type::cast(args[index]);
+
+#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index) \
+ RUNTIME_ASSERT(args[index]->Is##Type()); \
Handle<Type> name = args.at<Type>(index);
// Cast the given object to a boolean and store it in a variable with
// the given name. If the object is not a boolean call IllegalOperation
// and return.
-#define CONVERT_BOOLEAN_CHECKED(name, obj) \
- RUNTIME_ASSERT(obj->IsBoolean()); \
- bool name = (obj)->IsTrue();
+#define CONVERT_BOOLEAN_ARG_CHECKED(name, index) \
+ RUNTIME_ASSERT(args[index]->IsBoolean()); \
+ bool name = args[index]->IsTrue();
// Cast the given argument to a Smi and store its value in an int variable
// with the given name. If the argument is not a Smi call IllegalOperation
@@ -106,12 +106,20 @@
type name = NumberTo##Type(obj);
+// Cast the given argument to PropertyDetails and store its value in a
+// variable with the given name. If the argument is not a Smi call
+// IllegalOperation and return.
+#define CONVERT_PROPERTY_DETAILS_CHECKED(name, index) \
+ RUNTIME_ASSERT(args[index]->IsSmi()); \
+ PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
+
+
// Assert that the given argument has a valid value for a StrictModeFlag
// and store it in a StrictModeFlag variable with the given name.
-#define CONVERT_STRICT_MODE_ARG(name, index) \
- ASSERT(args[index]->IsSmi()); \
- ASSERT(args.smi_at(index) == kStrictMode || \
- args.smi_at(index) == kNonStrictMode); \
+#define CONVERT_STRICT_MODE_ARG_CHECKED(name, index) \
+ RUNTIME_ASSERT(args[index]->IsSmi()); \
+ RUNTIME_ASSERT(args.smi_at(index) == kStrictMode || \
+ args.smi_at(index) == kNonStrictMode); \
StrictModeFlag name = \
static_cast<StrictModeFlag>(args.smi_at(index));
@@ -558,9 +566,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
- CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3);
bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
@@ -584,9 +592,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
- CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3);
bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
@@ -610,9 +618,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
- CONVERT_ARG_CHECKED(FixedArray, elements, 2);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
// Check if boilerplate exists. If not, create it first.
Handle<Object> boilerplate(literals->get(literals_index), isolate);
@@ -630,9 +638,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
- CONVERT_ARG_CHECKED(FixedArray, elements, 2);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
// Check if boilerplate exists. If not, create it first.
Handle<Object> boilerplate(literals->get(literals_index), isolate);
@@ -691,28 +699,28 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSProxy, proxy, args[0]);
+ CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
return proxy->handler();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunctionProxy, proxy, args[0]);
+ CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
return proxy->call_trap();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunctionProxy, proxy, args[0]);
+ CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
return proxy->construct_trap();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSProxy, proxy, args[0]);
+ CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
proxy->Fix();
return isolate->heap()->undefined_value();
}
@@ -721,7 +729,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSSet, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
holder->set_table(*table);
return *holder;
@@ -731,7 +739,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSSet, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1]);
Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
table = ObjectHashSetAdd(table, key);
@@ -743,7 +751,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSSet, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1]);
Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
return isolate->heap()->ToBoolean(table->Contains(*key));
@@ -753,7 +761,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSSet, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1]);
Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
table = ObjectHashSetRemove(table, key);
@@ -765,7 +773,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSMap, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
holder->set_table(*table);
return *holder;
@@ -775,7 +783,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSMap, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Handle<Object> key(args[1]);
return ObjectHashTable::cast(holder->table())->Lookup(*key);
}
@@ -784,7 +792,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSMap, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Handle<Object> key(args[1]);
Handle<Object> value(args[2]);
Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
@@ -797,7 +805,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
ASSERT(weakmap->map()->inobject_properties() == 0);
Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
weakmap->set_table(*table);
@@ -809,8 +817,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
- CONVERT_ARG_CHECKED(JSReceiver, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
return ObjectHashTable::cast(weakmap->table())->Lookup(*key);
}
@@ -818,8 +826,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
- CONVERT_ARG_CHECKED(JSReceiver, key, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
Handle<Object> value(args[2]);
Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
@@ -840,7 +848,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSReceiver, input_obj, args[0]);
+ CONVERT_ARG_CHECKED(JSReceiver, input_obj, 0);
Object* obj = input_obj;
// We don't expect access checks to be needed on JSProxy objects.
ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
@@ -1009,8 +1017,8 @@
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms);
LookupResult result(isolate);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
// This could be an element.
uint32_t index;
@@ -1147,14 +1155,14 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSObject, obj, args[0]);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
return obj->PreventExtensions();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSObject, obj, args[0]);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
if (obj->IsJSGlobalProxy()) {
Object* proto = obj->GetPrototype();
if (proto->IsNull()) return isolate->heap()->false_value();
@@ -1168,9 +1176,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSRegExp, re, 0);
- CONVERT_ARG_CHECKED(String, pattern, 1);
- CONVERT_ARG_CHECKED(String, flags, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
Handle<Object> result = RegExpImpl::Compile(re, pattern, flags);
if (result.is_null()) return Failure::Exception();
return *result;
@@ -1180,7 +1188,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(FunctionTemplateInfo, data, 0);
+ CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
return *isolate->factory()->CreateApiFunction(data);
}
@@ -1195,9 +1203,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetTemplateField) {
ASSERT(args.length() == 2);
- CONVERT_CHECKED(HeapObject, templ, args[0]);
- CONVERT_CHECKED(Smi, field, args[1]);
- int index = field->value();
+ CONVERT_ARG_CHECKED(HeapObject, templ, 0);
+ CONVERT_SMI_ARG_CHECKED(index, 1)
int offset = index * kPointerSize + HeapObject::kHeaderSize;
InstanceType type = templ->map()->instance_type();
RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
@@ -1214,7 +1221,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(HeapObject, object, args[0]);
+ CONVERT_ARG_CHECKED(HeapObject, object, 0);
Map* old_map = object->map();
bool needs_access_checks = old_map->is_access_check_needed();
if (needs_access_checks) {
@@ -1233,7 +1240,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(HeapObject, object, args[0]);
+ CONVERT_ARG_CHECKED(HeapObject, object, 0);
Map* old_map = object->map();
if (!old_map->is_access_check_needed()) {
// Copy map so it won't interfere constructor's initial map.
@@ -1269,7 +1276,7 @@
isolate->context()->global());
Handle<Context> context = args.at<Context>(0);
- CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
CONVERT_SMI_ARG_CHECKED(flags, 2);
// Traverse the name/value pairs and set the properties.
@@ -1471,7 +1478,7 @@
RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
bool assign = args.length() == 3;
- CONVERT_ARG_CHECKED(String, name, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
GlobalObject* global = isolate->context()->global();
RUNTIME_ASSERT(args[1]->IsSmi());
CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
@@ -1528,7 +1535,7 @@
// of the constant is the first argument and the initial value
// is the second.
RUNTIME_ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, name, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
Handle<Object> value = args.at<Object>(1);
// Get the current global object from top.
@@ -1700,7 +1707,7 @@
Runtime_OptimizeObjectForAddingMultipleProperties) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_SMI_ARG_CHECKED(properties, 1);
if (object->HasFastProperties()) {
JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
@@ -1712,12 +1719,12 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
- CONVERT_ARG_CHECKED(String, subject, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
// Due to the way the JS calls are constructed this must be less than the
// length of a string, i.e. it is always a Smi. We check anyway for security.
CONVERT_SMI_ARG_CHECKED(index, 2);
- CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
RUNTIME_ASSERT(last_match_info->HasFastElements());
RUNTIME_ASSERT(index >= 0);
RUNTIME_ASSERT(index <= subject->length());
@@ -1769,8 +1776,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
AssertNoAllocation no_alloc;
ASSERT(args.length() == 5);
- CONVERT_CHECKED(JSRegExp, regexp, args[0]);
- CONVERT_CHECKED(String, source, args[1]);
+ CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
+ CONVERT_ARG_CHECKED(String, source, 1);
Object* global = args[2];
if (!global->IsTrue()) global = isolate->heap()->false_value();
@@ -1838,7 +1845,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSArray, prototype, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
// This is necessary to enable fast checks for absence of elements
// on Array.prototype and below.
prototype->set_elements(isolate->heap()->empty_fixed_array());
@@ -1867,7 +1874,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, holder, 0);
InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
@@ -1883,7 +1890,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSReceiver, callable, args[0]);
+ CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
@@ -1911,7 +1918,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
int index = args.smi_at(1);
Handle<String> pattern = args.at<String>(2);
Handle<String> flags = args.at<String>(3);
@@ -1942,7 +1949,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, f, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
return f->shared()->name();
}
@@ -1951,8 +1958,8 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSFunction, f, args[0]);
- CONVERT_CHECKED(String, name, args[1]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
+ CONVERT_ARG_CHECKED(String, name, 1);
f->shared()->set_name(name);
return isolate->heap()->undefined_value();
}
@@ -1961,7 +1968,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, f, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(
f->shared()->name_should_print_as_anonymous());
}
@@ -1970,7 +1977,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, f, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
f->shared()->set_name_should_print_as_anonymous(true);
return isolate->heap()->undefined_value();
}
@@ -1980,7 +1987,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, f, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
Object* obj = f->RemovePrototype();
if (obj->IsFailure()) return obj;
@@ -1992,7 +1999,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, fun, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, fun, 0);
Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
if (!script->IsScript()) return isolate->heap()->undefined_value();
@@ -2004,7 +2011,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, f, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
Handle<SharedFunctionInfo> shared(f->shared());
return *shared->GetSourceCode();
}
@@ -2014,7 +2021,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, fun, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, fun, 0);
int pos = fun->shared()->start_position();
return Smi::FromInt(pos);
}
@@ -2023,7 +2030,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetPositionForOffset) {
ASSERT(args.length() == 2);
- CONVERT_CHECKED(Code, code, args[0]);
+ CONVERT_ARG_CHECKED(Code, code, 0);
CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
RUNTIME_ASSERT(0 <= offset && offset < code->Size());
@@ -2037,8 +2044,8 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSFunction, fun, args[0]);
- CONVERT_CHECKED(String, name, args[1]);
+ CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+ CONVERT_ARG_CHECKED(String, name, 1);
fun->SetInstanceClassName(name);
return isolate->heap()->undefined_value();
}
@@ -2048,10 +2055,10 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSFunction, fun, args[0]);
- CONVERT_CHECKED(Smi, length, args[1]);
- fun->shared()->set_length(length->value());
- return length;
+ CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+ CONVERT_SMI_ARG_CHECKED(length, 1);
+ fun->shared()->set_length(length);
+ return isolate->heap()->undefined_value();
}
@@ -2059,7 +2066,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSFunction, fun, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, fun, 0);
ASSERT(fun->should_have_prototype());
Object* obj;
{ MaybeObject* maybe_obj =
@@ -2073,7 +2080,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
NoHandleAllocation ha;
RUNTIME_ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, function, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
MaybeObject* maybe_name =
isolate->heap()->AllocateStringFromAscii(CStrVector("prototype"));
@@ -2129,7 +2136,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, f, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
}
@@ -2138,7 +2145,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, f, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
return isolate->heap()->ToBoolean(f->IsBuiltin());
}
@@ -2147,7 +2154,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSFunction, target, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
Handle<Object> code = args.at<Object>(1);
Handle<Context> context(target->context());
@@ -2211,7 +2218,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_SMI_ARG_CHECKED(num, 1);
RUNTIME_ASSERT(num >= 0);
SetExpectedNofProperties(function, num);
@@ -2235,7 +2242,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, subject, args[0]);
+ CONVERT_ARG_CHECKED(String, subject, 0);
Object* index = args[1];
RUNTIME_ASSERT(index->IsNumber());
@@ -3212,7 +3219,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) {
ASSERT(args.length() == 4);
- CONVERT_CHECKED(String, subject, args[0]);
+ CONVERT_ARG_CHECKED(String, subject, 0);
if (!subject->IsFlat()) {
Object* flat_subject;
{ MaybeObject* maybe_flat_subject = subject->TryFlatten();
@@ -3223,7 +3230,7 @@
subject = String::cast(flat_subject);
}
- CONVERT_CHECKED(String, replacement, args[2]);
+ CONVERT_ARG_CHECKED(String, replacement, 2);
if (!replacement->IsFlat()) {
Object* flat_replacement;
{ MaybeObject* maybe_flat_replacement = replacement->TryFlatten();
@@ -3234,8 +3241,8 @@
replacement = String::cast(flat_replacement);
}
- CONVERT_CHECKED(JSRegExp, regexp, args[1]);
- CONVERT_CHECKED(JSArray, last_match_info, args[3]);
+ CONVERT_ARG_CHECKED(JSRegExp, regexp, 1);
+ CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
ASSERT(last_match_info->HasFastElements());
@@ -3305,9 +3312,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
ASSERT(args.length() == 3);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(String, subject, 0);
- CONVERT_ARG_CHECKED(String, search, 1);
- CONVERT_ARG_CHECKED(String, replace, 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
// If the cons string tree is too deep, we simply abort the recursion and
// retry with a flattened subject string.
@@ -3386,8 +3393,8 @@
HandleScope scope(isolate); // create a new handle scope
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(String, sub, 0);
- CONVERT_ARG_CHECKED(String, pat, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
Object* index = args[2];
uint32_t start_index;
@@ -3438,8 +3445,8 @@
HandleScope scope(isolate); // create a new handle scope
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(String, sub, 0);
- CONVERT_ARG_CHECKED(String, pat, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
Object* index = args[2];
uint32_t start_index;
@@ -3497,8 +3504,8 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, str1, args[0]);
- CONVERT_CHECKED(String, str2, args[1]);
+ CONVERT_ARG_CHECKED(String, str1, 0);
+ CONVERT_ARG_CHECKED(String, str2, 1);
if (str1 == str2) return Smi::FromInt(0); // Equal.
int str1_length = str1->length();
@@ -3545,7 +3552,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 3);
- CONVERT_CHECKED(String, value, args[0]);
+ CONVERT_ARG_CHECKED(String, value, 0);
int start, end;
// We have a fast integer-only case here to avoid a conversion to double in
// the common case where from and to are Smis.
@@ -3571,9 +3578,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
ASSERT_EQ(3, args.length());
- CONVERT_ARG_CHECKED(String, subject, 0);
- CONVERT_ARG_CHECKED(JSRegExp, regexp, 1);
- CONVERT_ARG_CHECKED(JSArray, regexp_info, 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
HandleScope handles;
Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info);
@@ -3964,11 +3971,11 @@
ASSERT(args.length() == 4);
HandleScope handles(isolate);
- CONVERT_ARG_CHECKED(String, subject, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
if (!subject->IsFlat()) FlattenString(subject);
- CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
- CONVERT_ARG_CHECKED(JSArray, last_match_info, 2);
- CONVERT_ARG_CHECKED(JSArray, result_array, 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
ASSERT(last_match_info->HasFastElements());
ASSERT(regexp->GetFlags().is_global());
@@ -4317,19 +4324,18 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
ASSERT(args.length() == 5);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
- CONVERT_CHECKED(String, name, args[1]);
- CONVERT_CHECKED(Smi, flag_setter, args[2]);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_SMI_ARG_CHECKED(flag_setter, 2);
Object* fun = args[3];
- CONVERT_CHECKED(Smi, flag_attr, args[4]);
+ CONVERT_SMI_ARG_CHECKED(unchecked, 4);
- int unchecked = flag_attr->value();
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
RUNTIME_ASSERT(!obj->IsNull());
RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined());
- return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr);
+ return obj->DefineAccessor(name, flag_setter == 0, fun, attr);
}
// Implements part of 8.12.9 DefineOwnProperty.
@@ -4341,12 +4347,11 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
ASSERT(args.length() == 4);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSObject, js_object, 0);
- CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
Handle<Object> obj_value = args.at<Object>(2);
- CONVERT_CHECKED(Smi, flag, args[3]);
+ CONVERT_SMI_ARG_CHECKED(unchecked, 3);
- int unchecked = flag->value();
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
@@ -4667,7 +4672,7 @@
StrictModeFlag strict_mode = kNonStrictMode;
if (args.length() == 5) {
- CONVERT_STRICT_MODE_ARG(strict_mode_flag, 4);
+ CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4);
strict_mode = strict_mode_flag;
}
@@ -4715,10 +4720,10 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
RUNTIME_ASSERT(args.length() == 5);
- CONVERT_ARG_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_SMI_ARG_CHECKED(store_index, 1);
Handle<Object> value = args.at<Object>(2);
- CONVERT_ARG_CHECKED(FixedArray, literals, 3);
+ CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
CONVERT_SMI_ARG_CHECKED(literal_index, 4);
HandleScope scope;
@@ -4758,13 +4763,12 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
NoHandleAllocation ha;
RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
- CONVERT_CHECKED(JSObject, object, args[0]);
- CONVERT_CHECKED(String, name, args[1]);
+ CONVERT_ARG_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_CHECKED(String, name, 1);
// Compute attributes.
PropertyAttributes attributes = NONE;
if (args.length() == 4) {
- CONVERT_CHECKED(Smi, value_obj, args[3]);
- int unchecked_value = value_obj->value();
+ CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
// Only attribute bits should be set.
RUNTIME_ASSERT(
(unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
@@ -4780,9 +4784,9 @@
NoHandleAllocation ha;
ASSERT(args.length() == 3);
- CONVERT_CHECKED(JSReceiver, object, args[0]);
- CONVERT_CHECKED(String, key, args[1]);
- CONVERT_STRICT_MODE_ARG(strict_mode, 2);
+ CONVERT_ARG_CHECKED(JSReceiver, object, 0);
+ CONVERT_ARG_CHECKED(String, key, 1);
+ CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
return object->DeleteProperty(key, (strict_mode == kStrictMode)
? JSReceiver::STRICT_DELETION
: JSReceiver::NORMAL_DELETION);
@@ -4810,7 +4814,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, key, args[1]);
+ CONVERT_ARG_CHECKED(String, key, 1);
uint32_t index;
const bool key_is_array_index = key->AsArrayIndex(&index);
@@ -4848,8 +4852,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
NoHandleAllocation na;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSReceiver, receiver, args[0]);
- CONVERT_CHECKED(String, key, args[1]);
+ CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
+ CONVERT_ARG_CHECKED(String, key, 1);
bool result = receiver->HasProperty(key);
if (isolate->has_pending_exception()) return Failure::Exception();
@@ -4860,10 +4864,10 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
NoHandleAllocation na;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSReceiver, receiver, args[0]);
- CONVERT_CHECKED(Smi, index, args[1]);
+ CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
+ CONVERT_SMI_ARG_CHECKED(index, 1);
- bool result = receiver->HasElement(index->value());
+ bool result = receiver->HasElement(index);
if (isolate->has_pending_exception()) return Failure::Exception();
return isolate->heap()->ToBoolean(result);
}
@@ -4873,8 +4877,8 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSObject, object, args[0]);
- CONVERT_CHECKED(String, key, args[1]);
+ CONVERT_ARG_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_CHECKED(String, key, 1);
uint32_t index;
if (key->AsArrayIndex(&index)) {
@@ -4919,7 +4923,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSReceiver, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
bool threw = false;
Handle<JSArray> result = GetKeysFor(object, &threw);
if (threw) return Failure::Exception();
@@ -4935,7 +4939,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSReceiver, raw_object, args[0]);
+ CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
if (raw_object->IsSimpleEnum()) return raw_object->map();
@@ -4976,7 +4980,7 @@
if (!args[0]->IsJSObject()) {
return isolate->heap()->undefined_value();
}
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
// Skip the global proxy as it has no properties and always delegates to the
// real global object.
@@ -5063,7 +5067,7 @@
if (!args[0]->IsJSObject()) {
return isolate->heap()->undefined_value();
}
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
@@ -5080,7 +5084,7 @@
if (!args[0]->IsJSObject()) {
return Smi::FromInt(0);
}
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
int result = 0;
if (obj->HasNamedInterceptor()) result |= 2;
@@ -5095,7 +5099,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetNamedInterceptorPropertyNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
if (obj->HasNamedInterceptor()) {
v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
@@ -5110,7 +5114,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetIndexedInterceptorElementNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
if (obj->HasIndexedInterceptor()) {
v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
@@ -5122,7 +5126,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
ASSERT_EQ(args.length(), 1);
- CONVERT_CHECKED(JSObject, raw_object, args[0]);
+ CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
HandleScope scope(isolate);
Handle<JSObject> object(raw_object);
@@ -5314,7 +5318,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(String, subject, args[0]);
+ CONVERT_ARG_CHECKED(String, subject, 0);
subject->TryFlatten();
// Fast case: short integer or some sorts of junk values.
@@ -5370,7 +5374,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSArray, codes, args[0]);
+ CONVERT_ARG_CHECKED(JSArray, codes, 0);
int length = Smi::cast(codes->length())->value();
// Check if the string can be ASCII.
@@ -5450,7 +5454,7 @@
const char hex_chars[] = "0123456789ABCDEF";
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(String, source, args[0]);
+ CONVERT_ARG_CHECKED(String, source, 0);
source->TryFlatten();
@@ -5568,7 +5572,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(String, source, args[0]);
+ CONVERT_ARG_CHECKED(String, source, 0);
source->TryFlatten();
@@ -5825,7 +5829,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
NoHandleAllocation ha;
- CONVERT_CHECKED(String, str, args[0]);
+ CONVERT_ARG_CHECKED(String, str, 0);
if (!str->IsFlat()) {
MaybeObject* try_flatten = str->TryFlatten();
Object* flat;
@@ -5849,7 +5853,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) {
NoHandleAllocation ha;
- CONVERT_CHECKED(String, str, args[0]);
+ CONVERT_ARG_CHECKED(String, str, 0);
if (!str->IsFlat()) {
MaybeObject* try_flatten = str->TryFlatten();
Object* flat;
@@ -5926,7 +5930,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSArray, array, args[0]);
+ CONVERT_ARG_CHECKED(JSArray, array, 0);
if (!array->HasFastElements()) return isolate->heap()->undefined_value();
FixedArray* elements = FixedArray::cast(array->elements());
@@ -5968,7 +5972,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
NoHandleAllocation ha;
- CONVERT_CHECKED(String, s, args[0]);
+ CONVERT_ARG_CHECKED(String, s, 0);
CONVERT_SMI_ARG_CHECKED(radix, 1);
s->TryFlatten();
@@ -5981,7 +5985,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
NoHandleAllocation ha;
- CONVERT_CHECKED(String, str, args[0]);
+ CONVERT_ARG_CHECKED(String, str, 0);
// ECMA-262 section 15.1.2.3, empty string is NaN
double value = StringToDouble(isolate->unicode_cache(),
@@ -6230,7 +6234,7 @@
Isolate* isolate,
unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) {
NoHandleAllocation ha;
- CONVERT_CHECKED(String, s, args[0]);
+ CONVERT_ARG_CHECKED(String, s, 0);
s = s->TryFlattenGetString();
const int length = s->length();
@@ -6292,9 +6296,9 @@
NoHandleAllocation ha;
ASSERT(args.length() == 3);
- CONVERT_CHECKED(String, s, args[0]);
- CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]);
- CONVERT_BOOLEAN_CHECKED(trimRight, args[2]);
+ CONVERT_ARG_CHECKED(String, s, 0);
+ CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
+ CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
s->TryFlatten();
int length = s->length();
@@ -6319,8 +6323,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
ASSERT(args.length() == 3);
HandleScope handle_scope(isolate);
- CONVERT_ARG_CHECKED(String, subject, 0);
- CONVERT_ARG_CHECKED(String, pattern, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
int subject_length = subject->length();
@@ -6441,7 +6445,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, s, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
s = FlattenGetString(s);
@@ -6492,7 +6496,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStringWrapper) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(String, value, args[0]);
+ CONVERT_ARG_CHECKED(String, value, 0);
return value->ToObject();
}
@@ -6683,8 +6687,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, str1, args[0]);
- CONVERT_CHECKED(String, str2, args[1]);
+ CONVERT_ARG_CHECKED(String, str1, 0);
+ CONVERT_ARG_CHECKED(String, str2, 1);
isolate->counters()->string_add_runtime()->Increment();
return isolate->heap()->AllocateConsString(str1, str2);
}
@@ -6732,13 +6736,13 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
- CONVERT_CHECKED(JSArray, array, args[0]);
+ CONVERT_ARG_CHECKED(JSArray, array, 0);
if (!args[1]->IsSmi()) {
isolate->context()->mark_out_of_memory();
return Failure::OutOfMemoryException();
}
int array_length = args.smi_at(1);
- CONVERT_CHECKED(String, special, args[2]);
+ CONVERT_ARG_CHECKED(String, special, 2);
// This assumption is used by the slice encoding in one or two smis.
ASSERT(Smi::kMaxValue >= String::kMaxLength);
@@ -6848,13 +6852,13 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
- CONVERT_CHECKED(JSArray, array, args[0]);
+ CONVERT_ARG_CHECKED(JSArray, array, 0);
if (!args[1]->IsSmi()) {
isolate->context()->mark_out_of_memory();
return Failure::OutOfMemoryException();
}
int array_length = args.smi_at(1);
- CONVERT_CHECKED(String, separator, args[2]);
+ CONVERT_ARG_CHECKED(String, separator, 2);
if (!array->HasFastElements()) {
return isolate->Throw(isolate->heap()->illegal_argument_symbol());
@@ -6972,11 +6976,11 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
- CONVERT_CHECKED(JSArray, elements_array, args[0]);
+ CONVERT_ARG_CHECKED(JSArray, elements_array, 0);
RUNTIME_ASSERT(elements_array->HasFastElements() ||
elements_array->HasFastSmiOnlyElements());
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
- CONVERT_CHECKED(String, separator, args[2]);
+ CONVERT_ARG_CHECKED(String, separator, 2);
// elements_array is fast-mode JSarray of alternating positions
// (increasing order) and strings.
// array_length is length of original array (used to add separators);
@@ -6998,7 +7002,8 @@
FixedArray* elements = FixedArray::cast(elements_array->elements());
for (int i = 0; i < elements_length; i += 2) {
RUNTIME_ASSERT(elements->get(i)->IsNumber());
- CONVERT_CHECKED(String, string, elements->get(i + 1));
+ RUNTIME_ASSERT(elements->get(i + 1)->IsString());
+ String* string = String::cast(elements->get(i + 1));
int length = string->length();
if (is_ascii && !string->IsAsciiRepresentation()) {
is_ascii = false;
@@ -7156,8 +7161,8 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, x, args[0]);
- CONVERT_CHECKED(String, y, args[1]);
+ CONVERT_ARG_CHECKED(String, x, 0);
+ CONVERT_ARG_CHECKED(String, y, 1);
bool not_equal = !x->Equals(y);
// This is slightly convoluted because the value that signifies
@@ -7188,12 +7193,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
-
- // Extract the integer values from the Smis.
- CONVERT_CHECKED(Smi, x, args[0]);
- CONVERT_CHECKED(Smi, y, args[1]);
- int x_value = x->value();
- int y_value = y->value();
+ CONVERT_SMI_ARG_CHECKED(x_value, 0);
+ CONVERT_SMI_ARG_CHECKED(y_value, 1);
// If the integers are equal so are the string representations.
if (x_value == y_value) return Smi::FromInt(EQUAL);
@@ -7333,8 +7334,8 @@
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, x, args[0]);
- CONVERT_CHECKED(String, y, args[1]);
+ CONVERT_ARG_CHECKED(String, x, 0);
+ CONVERT_ARG_CHECKED(String, y, 1);
isolate->counters()->string_compare_runtime()->Increment();
@@ -7941,7 +7942,7 @@
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(t, 0);
- CONVERT_CHECKED(JSArray, res_array, args[1]);
+ CONVERT_ARG_CHECKED(JSArray, res_array, 1);
int year, month, day;
DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day);
@@ -8096,9 +8097,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(Context, context, 0);
- CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
- CONVERT_BOOLEAN_CHECKED(pretenure, args[2]);
+ CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
+ CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
+ CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
// The caller ensures that we pretenure closures that are assigned
// directly to properties.
@@ -8164,7 +8165,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- CONVERT_ARG_CHECKED(JSFunction, bound_function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
RUNTIME_ASSERT(args[3]->IsNumber());
Handle<Object> bindee = args.at<Object>(1);
@@ -8222,7 +8223,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
HandleScope handles(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
if (callable->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
if (function->shared()->bound()) {
@@ -8239,7 +8240,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
// First argument is a function to use as a constructor.
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
RUNTIME_ASSERT(function->shared()->bound());
// The argument is a bound function. Extract its bound arguments
@@ -8380,7 +8381,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
function->shared()->CompleteInobjectSlackTracking();
TrySettingInlineConstructStub(isolate, function);
@@ -8569,7 +8570,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
if (!function->IsOptimized()) return isolate->heap()->undefined_value();
Deoptimizer::DeoptimizeFunction(*function);
@@ -8590,7 +8591,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
function->MarkForLazyRecompilation();
return isolate->heap()->undefined_value();
@@ -8608,7 +8609,7 @@
if (FLAG_always_opt) {
return Smi::FromInt(3); // 3 == "always".
}
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes".
: Smi::FromInt(2); // 2 == "no".
}
@@ -8617,7 +8618,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
return Smi::FromInt(function->shared()->opt_count());
}
@@ -8625,7 +8626,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
// We're not prepared to handle a function with arguments object.
ASSERT(!function->shared()->uses_arguments());
@@ -8754,9 +8755,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
HandleScope scope(isolate);
ASSERT(args.length() >= 2);
- CONVERT_CHECKED(JSReceiver, fun, args[args.length() - 1]);
- Object* receiver = args[0];
int argc = args.length() - 2;
+ CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
+ Object* receiver = args[0];
// If there are too many arguments, allocate argv via malloc.
const int argv_small_size = 10;
@@ -8790,9 +8791,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
HandleScope scope(isolate);
ASSERT(args.length() == 5);
- CONVERT_ARG_CHECKED(JSReceiver, fun, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
Handle<Object> receiver = args.at<Object>(1);
- CONVERT_ARG_CHECKED(JSObject, arguments, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
CONVERT_SMI_ARG_CHECKED(offset, 3);
CONVERT_SMI_ARG_CHECKED(argc, 4);
ASSERT(offset >= 0);
@@ -8842,7 +8843,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, function, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
int length = function->shared()->scope_info()->ContextLength();
Object* result;
{ MaybeObject* maybe_result =
@@ -8954,8 +8955,8 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(Context, context, 0);
- CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
int index;
PropertyAttributes attributes;
@@ -9147,8 +9148,8 @@
ASSERT(args.length() == 4);
Handle<Object> value(args[0], isolate);
- CONVERT_ARG_CHECKED(Context, context, 1);
- CONVERT_ARG_CHECKED(String, name, 2);
+ CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
StrictModeFlag strict_mode = (language_mode == CLASSIC_MODE)
? kNonStrictMode : kStrictMode;
@@ -9381,10 +9382,10 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, str, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
FlattenString(str);
- CONVERT_ARG_CHECKED(JSArray, output, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
MaybeObject* maybe_result_array =
output->EnsureCanContainHeapObjectElements();
@@ -9454,7 +9455,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
HandleScope scope(isolate);
ASSERT_EQ(1, args.length());
- CONVERT_ARG_CHECKED(String, source, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
source = Handle<String>(source->TryFlattenGetString());
// Optimized fast case where we only have ASCII characters.
@@ -9493,7 +9494,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
HandleScope scope(isolate);
ASSERT_EQ(1, args.length());
- CONVERT_ARG_CHECKED(String, source, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
// Extract global context.
Handle<Context> context(isolate->context()->global_context());
@@ -9584,7 +9585,7 @@
// as specified in ECMA262, 15.3.5.2.
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, func, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
Handle<Map> map = func->shared()->is_classic_mode()
? isolate->function_instance_map()
@@ -9602,7 +9603,7 @@
// Use as fallback for allocation in generated code when NewSpace
// is full.
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(Smi, size_smi, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
int size = size_smi->value();
RUNTIME_ASSERT(IsAligned(size, kPointerSize));
RUNTIME_ASSERT(size > 0);
@@ -9624,8 +9625,8 @@
// false otherwise.
RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSArray, array, args[0]);
- CONVERT_CHECKED(JSObject, element, args[1]);
+ CONVERT_ARG_CHECKED(JSArray, array, 0);
+ CONVERT_ARG_CHECKED(JSObject, element, 1);
RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements());
int length = Smi::cast(array->length())->value();
FixedArray* elements = FixedArray::cast(array->elements());
@@ -10116,7 +10117,7 @@
ASSERT(args.length() == 1);
HandleScope handle_scope(isolate);
- CONVERT_ARG_CHECKED(JSArray, arguments, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
int argument_count = static_cast<int>(arguments->length()->Number());
RUNTIME_ASSERT(arguments->HasFastElements());
Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
@@ -10211,7 +10212,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(String, string, args[0]);
+ CONVERT_ARG_CHECKED(String, string, 0);
StringInputBuffer buffer(string);
while (buffer.has_more()) {
uint16_t character = buffer.GetNext();
@@ -10227,7 +10228,7 @@
// Returns the number of non-undefined elements collected.
RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSObject, object, args[0]);
+ CONVERT_ARG_CHECKED(JSObject, object, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
return object->PrepareElementsForSort(limit);
}
@@ -10236,8 +10237,8 @@
// Move contents of argument 0 (an array) to argument 1 (an array)
RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSArray, from, args[0]);
- CONVERT_CHECKED(JSArray, to, args[1]);
+ CONVERT_ARG_CHECKED(JSArray, from, 0);
+ CONVERT_ARG_CHECKED(JSArray, to, 1);
FixedArrayBase* new_elements = from->elements();
MaybeObject* maybe_new_map;
ElementsKind elements_kind;
@@ -10268,7 +10269,7 @@
// How many elements does this object/array have?
RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSObject, object, args[0]);
+ CONVERT_ARG_CHECKED(JSObject, object, 0);
HeapObject* elements = object->elements();
if (elements->IsDictionary()) {
int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
@@ -10286,7 +10287,7 @@
ASSERT_EQ(3, args.length());
- CONVERT_ARG_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
Handle<Object> key1 = args.at<Object>(1);
Handle<Object> key2 = args.at<Object>(2);
@@ -10319,7 +10320,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSObject, array, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
if (array->elements()->IsDictionary()) {
// Create an array and get all the keys into it, then remove all the
@@ -10368,27 +10369,26 @@
// Compute attributes.
PropertyAttributes attributes = NONE;
if (args.length() == 5) {
- CONVERT_CHECKED(Smi, attrs, args[4]);
- int value = attrs->value();
+ CONVERT_SMI_ARG_CHECKED(value, 4);
// Only attribute bits should be set.
ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
attributes = static_cast<PropertyAttributes>(value);
}
- CONVERT_CHECKED(JSObject, obj, args[0]);
- CONVERT_CHECKED(String, name, args[1]);
- CONVERT_CHECKED(Smi, flag, args[2]);
- CONVERT_CHECKED(JSFunction, fun, args[3]);
- return obj->DefineAccessor(name, flag->value() == 0, fun, attributes);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_SMI_ARG_CHECKED(flag, 2);
+ CONVERT_ARG_CHECKED(JSFunction, fun, 3);
+ return obj->DefineAccessor(name, flag == 0, fun, attributes);
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
ASSERT(args.length() == 3);
- CONVERT_CHECKED(JSObject, obj, args[0]);
- CONVERT_CHECKED(String, name, args[1]);
- CONVERT_CHECKED(Smi, flag, args[2]);
- return obj->LookupAccessor(name, flag->value() == 0);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_SMI_ARG_CHECKED(flag, 2);
+ return obj->LookupAccessor(name, flag == 0);
}
@@ -10406,8 +10406,8 @@
}
-static StackFrame::Id UnwrapFrameId(Smi* wrapped) {
- return static_cast<StackFrame::Id>(wrapped->value() << 2);
+static StackFrame::Id UnwrapFrameId(int wrapped) {
+ return static_cast<StackFrame::Id>(wrapped << 2);
}
@@ -10510,8 +10510,8 @@
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
// Make sure to set the current context to the context before the debugger was
// entered (if the debugger is entered). The reason for switching context here
@@ -10608,8 +10608,8 @@
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
LookupResult result(isolate);
obj->Lookup(*name, &result);
@@ -10624,9 +10624,8 @@
// args[0]: smi with property details.
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyTypeFromDetails) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(Smi, details, args[0]);
- PropertyType type = PropertyDetails(details).type();
- return Smi::FromInt(static_cast<int>(type));
+ CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
+ return Smi::FromInt(static_cast<int>(details.type()));
}
@@ -10634,9 +10633,8 @@
// args[0]: smi with property details.
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(Smi, details, args[0]);
- PropertyAttributes attributes = PropertyDetails(details).attributes();
- return Smi::FromInt(static_cast<int>(attributes));
+ CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
+ return Smi::FromInt(static_cast<int>(details.attributes()));
}
@@ -10644,9 +10642,8 @@
// args[0]: smi with property details.
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(Smi, details, args[0]);
- int index = PropertyDetails(details).index();
- return Smi::FromInt(index);
+ CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
+ return Smi::FromInt(details.index());
}
@@ -10656,9 +10653,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
RUNTIME_ASSERT(obj->HasNamedInterceptor());
- CONVERT_ARG_CHECKED(String, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
PropertyAttributes attributes;
return obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
@@ -10671,7 +10668,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
RUNTIME_ASSERT(obj->HasIndexedInterceptor());
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
@@ -11283,6 +11280,29 @@
}
+// Create a plain JSObject which materializes the module scope for the specified
+// module context.
+static Handle<JSObject> MaterializeModuleScope(
+ Isolate* isolate,
+ Handle<Context> context) {
+ ASSERT(context->IsModuleContext());
+ Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+
+ // Allocate and initialize a JSObject with all the members of the debugged
+ // module.
+ Handle<JSObject> module_scope =
+ isolate->factory()->NewJSObject(isolate->object_function());
+
+ // Fill all context locals.
+ if (!CopyContextLocalsToScopeObject(
+ isolate, scope_info, context, module_scope)) {
+ return Handle<JSObject>();
+ }
+
+ return module_scope;
+}
+
+
// Iterate over the actual scopes visible from a stack frame. The iteration
// proceeds from the innermost visible nested scope outwards. All scopes are
// backed by an actual context except the local scope, which is inserted
@@ -11295,7 +11315,8 @@
ScopeTypeWith,
ScopeTypeClosure,
ScopeTypeCatch,
- ScopeTypeBlock
+ ScopeTypeBlock,
+ ScopeTypeModule
};
ScopeIterator(Isolate* isolate,
@@ -11418,6 +11439,9 @@
ASSERT(context_->IsFunctionContext() ||
!scope_info->HasContext());
return ScopeTypeLocal;
+ case MODULE_SCOPE:
+ ASSERT(context_->IsModuleContext());
+ return ScopeTypeModule;
case GLOBAL_SCOPE:
ASSERT(context_->IsGlobalContext());
return ScopeTypeGlobal;
@@ -11448,6 +11472,9 @@
if (context_->IsBlockContext()) {
return ScopeTypeBlock;
}
+ if (context_->IsModuleContext()) {
+ return ScopeTypeModule;
+ }
ASSERT(context_->IsWithContext());
return ScopeTypeWith;
}
@@ -11471,6 +11498,8 @@
return MaterializeClosure(isolate_, CurrentContext());
case ScopeIterator::ScopeTypeBlock:
return MaterializeBlockScope(isolate_, CurrentContext());
+ case ScopeIterator::ScopeTypeModule:
+ return MaterializeModuleScope(isolate_, CurrentContext());
}
UNREACHABLE();
return Handle<JSObject>();
@@ -11575,7 +11604,7 @@
RUNTIME_ARGUMENTS(isolate, args));
if (!maybe_check->ToObject(&check)) return maybe_check;
}
- CONVERT_CHECKED(Smi, wrapped_id, args[1]);
+ CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
// Get the frame where the debugging is performed.
StackFrame::Id id = UnwrapFrameId(wrapped_id);
@@ -11617,7 +11646,7 @@
RUNTIME_ARGUMENTS(isolate, args));
if (!maybe_check->ToObject(&check)) return maybe_check;
}
- CONVERT_CHECKED(Smi, wrapped_id, args[1]);
+ CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
@@ -11757,7 +11786,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDisableBreak) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_BOOLEAN_CHECKED(disable_break, args[0]);
+ CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
isolate->debug()->set_disable_break(disable_break);
return isolate->heap()->undefined_value();
}
@@ -11767,7 +11796,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
Handle<SharedFunctionInfo> shared(fun->shared());
// Find the number of break points
Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared);
@@ -11785,7 +11814,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
Handle<SharedFunctionInfo> shared(fun->shared());
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
@@ -11891,7 +11920,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSValue, wrapper, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
Handle<Object> break_point_object_arg = args.at<Object>(2);
@@ -11941,7 +11970,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
RUNTIME_ASSERT(args[0]->IsNumber());
- CONVERT_BOOLEAN_CHECKED(enable, args[1]);
+ CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
// If the number doesn't match an enum value, the ChangeBreakOnException
// function will default to affecting caught exceptions.
@@ -12156,10 +12185,10 @@
return maybe_check_result;
}
}
- CONVERT_CHECKED(Smi, wrapped_id, args[1]);
+ CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
- CONVERT_ARG_CHECKED(String, source, 3);
- CONVERT_BOOLEAN_CHECKED(disable_break, args[4]);
+ CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
+ CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
Handle<Object> additional_context(args[5]);
// Handle the processing of break.
@@ -12295,8 +12324,8 @@
return maybe_check_result;
}
}
- CONVERT_ARG_CHECKED(String, source, 1);
- CONVERT_BOOLEAN_CHECKED(disable_break, args[2]);
+ CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
+ CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
Handle<Object> additional_context(args[3]);
// Handle the processing of break.
@@ -12469,7 +12498,7 @@
// Object* locals that are not protected by handles.
// Check parameters.
- CONVERT_CHECKED(JSObject, target, args[0]);
+ CONVERT_ARG_CHECKED(JSObject, target, 0);
Object* instance_filter = args[1];
RUNTIME_ASSERT(instance_filter->IsUndefined() ||
instance_filter->IsJSObject());
@@ -12557,7 +12586,7 @@
"%DebugConstructedBy");
// Check parameters.
- CONVERT_CHECKED(JSFunction, constructor, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, constructor, 0);
CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
RUNTIME_ASSERT(max_references >= 0);
@@ -12601,7 +12630,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSObject, obj, args[0]);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
// Use the __proto__ accessor.
return Accessors::ObjectPrototype.getter(obj, NULL);
@@ -12620,7 +12649,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
// Get the function and make sure it is compiled.
- CONVERT_ARG_CHECKED(JSFunction, func, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
Handle<SharedFunctionInfo> shared(func->shared());
if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
return Failure::Exception();
@@ -12636,7 +12665,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
// Get the function and make sure it is compiled.
- CONVERT_ARG_CHECKED(JSFunction, func, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
Handle<SharedFunctionInfo> shared(func->shared());
if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) {
return Failure::Exception();
@@ -12651,7 +12680,7 @@
NoHandleAllocation ha;
ASSERT(args.length() == 1);
- CONVERT_CHECKED(JSFunction, f, args[0]);
+ CONVERT_ARG_CHECKED(JSFunction, f, 0);
return f->shared()->inferred_name();
}
@@ -12688,7 +12717,7 @@
Runtime_LiveEditFindSharedFunctionInfosForScript) {
ASSERT(args.length() == 1);
HandleScope scope(isolate);
- CONVERT_CHECKED(JSValue, script_value, args[0]);
+ CONVERT_ARG_CHECKED(JSValue, script_value, 0);
Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
@@ -12734,8 +12763,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_CHECKED(JSValue, script, args[0]);
- CONVERT_ARG_CHECKED(String, source, 1);
+ CONVERT_ARG_CHECKED(JSValue, script, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source);
@@ -12753,13 +12782,12 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
ASSERT(args.length() == 3);
HandleScope scope(isolate);
- CONVERT_CHECKED(JSValue, original_script_value, args[0]);
- CONVERT_ARG_CHECKED(String, new_source, 1);
+ CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
Handle<Object> old_script_name(args[2], isolate);
- CONVERT_CHECKED(Script, original_script_pointer,
- original_script_value->value());
- Handle<Script> original_script(original_script_pointer);
+ RUNTIME_ASSERT(original_script_value->value()->IsScript());
+ Handle<Script> original_script(Script::cast(original_script_value->value()));
Object* old_script = LiveEdit::ChangeScriptSource(original_script,
new_source,
@@ -12777,7 +12805,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
ASSERT(args.length() == 1);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSArray, shared_info, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
return LiveEdit::FunctionSourceUpdated(shared_info);
}
@@ -12786,8 +12814,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0);
- CONVERT_ARG_CHECKED(JSArray, shared_info, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
}
@@ -12802,7 +12830,8 @@
if (function_object->IsJSValue()) {
Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
if (script_object->IsJSValue()) {
- CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value());
+ RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
+ Script* script = Script::cast(JSValue::cast(*script_object)->value());
script_object = Handle<Object>(script, isolate);
}
@@ -12822,9 +12851,9 @@
ASSERT(args.length() == 3);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0);
- CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1);
- CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
subst_wrapper);
@@ -12841,8 +12870,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
- CONVERT_ARG_CHECKED(JSArray, position_change_array, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
}
@@ -12855,8 +12884,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
- CONVERT_BOOLEAN_CHECKED(do_drop, args[1]);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
+ CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
}
@@ -12867,8 +12896,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(String, s1, 0);
- CONVERT_ARG_CHECKED(String, s2, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
return *LiveEdit::CompareStrings(s1, s2);
}
@@ -12879,7 +12908,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
Handle<Code> code(function->code(), isolate);
@@ -12916,8 +12945,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
ASSERT(args.length() == 2);
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
- CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+ CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
Handle<Object> result;
bool pending_exception;
@@ -12941,7 +12970,7 @@
// Sets a v8 flag.
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
- CONVERT_CHECKED(String, arg, args[0]);
+ CONVERT_ARG_CHECKED(String, arg, 0);
SmartArrayPointer<char> flags =
arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
FlagList::SetFlagsFromString(*flags, StrLength(*flags));
@@ -13011,7 +13040,7 @@
CONVERT_SMI_ARG_CHECKED(id2, 1);
CONVERT_SMI_ARG_CHECKED(start, 2);
CONVERT_SMI_ARG_CHECKED(count, 3);
- CONVERT_ARG_CHECKED(JSObject, filter_obj, 4);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 4);
EnterDebugger enter_debugger;
return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
#else
@@ -13038,7 +13067,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjId) {
#ifdef LIVE_OBJECT_LIST
HandleScope scope;
- CONVERT_ARG_CHECKED(String, address, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, address, 0);
Object* result = LiveObjectList::GetObjId(address);
return result;
#else
@@ -13056,7 +13085,7 @@
RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi());
- CONVERT_ARG_CHECKED(JSObject, filter_obj, 5);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 5);
Handle<JSObject> instance_filter;
if (args[1]->IsJSObject()) {
@@ -13157,7 +13186,7 @@
HandleScope scope;
CONVERT_SMI_ARG_CHECKED(id1, 0);
CONVERT_SMI_ARG_CHECKED(id2, 1);
- CONVERT_ARG_CHECKED(JSObject, filter_obj, 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, filter_obj, 2);
EnterDebugger enter_debugger;
return LiveObjectList::Summarize(id1, id2, filter_obj);
@@ -13225,7 +13254,7 @@
ASSERT(args.length() == 1);
- CONVERT_CHECKED(String, script_name, args[0]);
+ CONVERT_ARG_CHECKED(String, script_name, 0);
// Find the requested script.
Handle<Object> result =
@@ -13280,7 +13309,7 @@
// native code offset.
RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
ASSERT_EQ(args.length(), 3);
- CONVERT_ARG_CHECKED(JSObject, error_object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
Handle<Object> caller = args.at<Object>(1);
CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
@@ -13365,7 +13394,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
// This is only called from codegen, so checks might be more lax.
- CONVERT_CHECKED(JSFunctionResultCache, cache, args[0]);
+ CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
Object* key = args[1];
int finger_index = cache->finger_index();
@@ -13461,8 +13490,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewMessageObject) {
HandleScope scope(isolate);
- CONVERT_ARG_CHECKED(String, type, 0);
- CONVERT_ARG_CHECKED(JSArray, arguments, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, type, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 1);
return *isolate->factory()->NewJSMessageObject(
type,
arguments,
@@ -13475,25 +13504,25 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetType) {
- CONVERT_CHECKED(JSMessageObject, message, args[0]);
+ CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return message->type();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetArguments) {
- CONVERT_CHECKED(JSMessageObject, message, args[0]);
+ CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return message->arguments();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetStartPosition) {
- CONVERT_CHECKED(JSMessageObject, message, args[0]);
+ CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return Smi::FromInt(message->start_position());
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
- CONVERT_CHECKED(JSMessageObject, message, args[0]);
+ CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return message->script();
}
@@ -13547,8 +13576,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
ASSERT(args.length() == 2);
- CONVERT_CHECKED(String, format, args[0]);
- CONVERT_CHECKED(JSArray, elms, args[1]);
+ CONVERT_ARG_CHECKED(String, format, 0);
+ CONVERT_ARG_CHECKED(JSArray, elms, 1);
String::FlatContent format_content = format->GetFlatContent();
RUNTIME_ASSERT(format_content.IsAscii());
Vector<const char> chars = format_content.ToAsciiVector();
@@ -13565,7 +13594,7 @@
#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
- CONVERT_CHECKED(JSObject, obj, args[0]); \
+ CONVERT_ARG_CHECKED(JSObject, obj, 0); \
return isolate->heap()->ToBoolean(obj->Has##Name()); \
}
@@ -13589,8 +13618,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
ASSERT(args.length() == 2);
- CONVERT_CHECKED(JSObject, obj1, args[0]);
- CONVERT_CHECKED(JSObject, obj2, args[1]);
+ CONVERT_ARG_CHECKED(JSObject, obj1, 0);
+ CONVERT_ARG_CHECKED(JSObject, obj2, 1);
return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
}
diff --git a/src/runtime.js b/src/runtime.js
index d0cdb3e..53d9a39 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -39,16 +39,16 @@
-----------------------------------
*/
-// The following const declarations are shared with other native JS files.
-// They are all declared at this one spot to avoid const redeclaration errors.
-const $Object = global.Object;
-const $Array = global.Array;
-const $String = global.String;
-const $Number = global.Number;
-const $Function = global.Function;
-const $Boolean = global.Boolean;
-const $NaN = 0/0;
-const builtins = this;
+// The following declarations are shared with other native JS files.
+// They are all declared at this one spot to avoid redeclaration errors.
+var $Object = global.Object;
+var $Array = global.Array;
+var $String = global.String;
+var $Number = global.Number;
+var $Function = global.Function;
+var $Boolean = global.Boolean;
+var $NaN = 0/0;
+var builtins = this;
// ECMA-262 Section 11.9.3.
function EQUALS(y) {
diff --git a/src/scopes.cc b/src/scopes.cc
index 35d804d..9835108 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -704,6 +704,7 @@
switch (type) {
case EVAL_SCOPE: return "eval";
case FUNCTION_SCOPE: return "function";
+ case MODULE_SCOPE: return "module";
case GLOBAL_SCOPE: return "global";
case CATCH_SCOPE: return "catch";
case BLOCK_SCOPE: return "block";
diff --git a/src/scopes.h b/src/scopes.h
index 06202c4..5b645f2 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -263,6 +263,7 @@
// Specific scope types.
bool is_eval_scope() const { return type_ == EVAL_SCOPE; }
bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
+ bool is_module_scope() const { return type_ == MODULE_SCOPE; }
bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
bool is_catch_scope() const { return type_ == CATCH_SCOPE; }
bool is_block_scope() const { return type_ == BLOCK_SCOPE; }
diff --git a/src/string.js b/src/string.js
index 2d68961..02f5c98 100644
--- a/src/string.js
+++ b/src/string.js
@@ -28,8 +28,8 @@
// This file relies on the fact that the following declaration has been made
// in runtime.js:
-// const $String = global.String;
-// const $NaN = 0/0;
+// var $String = global.String;
+// var $NaN = 0/0;
// Set the String function and constructor.
@@ -588,11 +588,8 @@
limit = (IS_UNDEFINED(limit)) ? 0xffffffff : TO_UINT32(limit);
// ECMA-262 says that if separator is undefined, the result should
- // be an array of size 1 containing the entire string. SpiderMonkey
- // and KJS have this behavior only when no separator is given. If
- // undefined is explicitly given, they convert it to a string and
- // use that. We do as SpiderMonkey and KJS.
- if (%_ArgumentsLength() === 0) {
+ // be an array of size 1 containing the entire string.
+ if (IS_UNDEFINED(separator)) {
return [subject];
}
diff --git a/src/type-info.cc b/src/type-info.cc
index 0b6e08f..2fb4e2a 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -573,7 +573,11 @@
void TypeFeedbackOracle::CreateDictionary(Handle<Code> code,
ZoneList<RelocInfo>* infos) {
DisableAssertNoAllocation allocation_allowed;
- int length = infos->length() + code->type_feedback_cells()->CellCount();
+ int cell_count = code->type_feedback_info()->IsTypeFeedbackInfo()
+ ? TypeFeedbackInfo::cast(code->type_feedback_info())->
+ type_feedback_cells()->CellCount()
+ : 0;
+ int length = infos->length() + cell_count;
byte* old_start = code->instruction_start();
dictionary_ = FACTORY->NewUnseededNumberDictionary(length);
byte* new_start = code->instruction_start();
@@ -643,7 +647,10 @@
void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) {
- Handle<TypeFeedbackCells> cache(code->type_feedback_cells());
+ Object* raw_info = code->type_feedback_info();
+ if (!raw_info->IsTypeFeedbackInfo()) return;
+ Handle<TypeFeedbackCells> cache(
+ TypeFeedbackInfo::cast(raw_info)->type_feedback_cells());
for (int i = 0; i < cache->CellCount(); i++) {
unsigned ast_id = cache->AstId(i)->value();
Object* value = cache->Cell(i)->value();
diff --git a/src/uri.js b/src/uri.js
index e76104a..b195f3d 100644
--- a/src/uri.js
+++ b/src/uri.js
@@ -250,7 +250,7 @@
// ECMA-262 - 15.1.3.1.
function URIDecode(uri) {
- function reservedPredicate(cc) {
+ var reservedPredicate = function(cc) {
// #$
if (35 <= cc && cc <= 36) return true;
// &
@@ -267,7 +267,7 @@
if (63 <= cc && cc <= 64) return true;
return false;
- }
+ };
var string = ToString(uri);
return Decode(string, reservedPredicate);
}
@@ -275,7 +275,7 @@
// ECMA-262 - 15.1.3.2.
function URIDecodeComponent(component) {
- function reservedPredicate(cc) { return false; }
+ var reservedPredicate = function(cc) { return false; };
var string = ToString(component);
return Decode(string, reservedPredicate);
}
@@ -296,7 +296,7 @@
// ECMA-262 - 15.1.3.3.
function URIEncode(uri) {
- function unescapePredicate(cc) {
+ var unescapePredicate = function(cc) {
if (isAlphaNumeric(cc)) return true;
// !
if (cc == 33) return true;
@@ -316,7 +316,7 @@
if (cc == 126) return true;
return false;
- }
+ };
var string = ToString(uri);
return Encode(string, unescapePredicate);
@@ -325,7 +325,7 @@
// ECMA-262 - 15.1.3.4
function URIEncodeComponent(component) {
- function unescapePredicate(cc) {
+ var unescapePredicate = function(cc) {
if (isAlphaNumeric(cc)) return true;
// !
if (cc == 33) return true;
@@ -339,7 +339,7 @@
if (cc == 126) return true;
return false;
- }
+ };
var string = ToString(component);
return Encode(string, unescapePredicate);
diff --git a/src/v8globals.h b/src/v8globals.h
index ff3ad8d..bfc5e23 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -461,6 +461,7 @@
enum ScopeType {
EVAL_SCOPE, // The top-level scope for an eval source.
FUNCTION_SCOPE, // The top-level scope for a function.
+ MODULE_SCOPE, // The scope introduced by a module literal
GLOBAL_SCOPE, // The top-level scope for a program or a top-level eval.
CATCH_SCOPE, // The scope introduced by catch.
BLOCK_SCOPE, // The scope introduced by a new block.
diff --git a/src/v8natives.js b/src/v8natives.js
index 1d54e28..381d341 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -28,18 +28,18 @@
// This file relies on the fact that the following declarations have been made
//
// in runtime.js:
-// const $Object = global.Object;
-// const $Boolean = global.Boolean;
-// const $Number = global.Number;
-// const $Function = global.Function;
-// const $Array = global.Array;
-// const $NaN = 0/0;
+// var $Object = global.Object;
+// var $Boolean = global.Boolean;
+// var $Number = global.Number;
+// var $Function = global.Function;
+// var $Array = global.Array;
+// var $NaN = 0/0;
//
// in math.js:
-// const $floor = MathFloor
+// var $floor = MathFloor
-const $isNaN = GlobalIsNaN;
-const $isFinite = GlobalIsFinite;
+var $isNaN = GlobalIsNaN;
+var $isFinite = GlobalIsFinite;
// ----------------------------------------------------------------------------
diff --git a/src/version.cc b/src/version.cc
index 69c807e..6b811f4 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 9
-#define BUILD_NUMBER 7
+#define BUILD_NUMBER 8
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 9ce1af8..5397cd5 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -1640,6 +1640,8 @@
void Assembler::movzxbq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
+ // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
+ // there is no need to make this a 64 bit operation.
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0xB6);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 4129db6..7bde564 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3239,17 +3239,25 @@
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- if (instr->index()->IsConstantOperand()) {
- if (instr->length()->IsRegister()) {
- __ cmpq(ToRegister(instr->length()),
+ if (instr->length()->IsRegister()) {
+ Register reg = ToRegister(instr->length());
+ if (FLAG_debug_code) {
+ __ AbortIfNotZeroExtended(reg);
+ }
+ if (instr->index()->IsConstantOperand()) {
+ __ cmpq(reg,
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
} else {
- __ cmpq(ToOperand(instr->length()),
- Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+ Register reg2 = ToRegister(instr->index());
+ if (FLAG_debug_code) {
+ __ AbortIfNotZeroExtended(reg2);
+ }
+ __ cmpq(reg, reg2);
}
} else {
- if (instr->length()->IsRegister()) {
- __ cmpq(ToRegister(instr->length()), ToRegister(instr->index()));
+ if (instr->index()->IsConstantOperand()) {
+ __ cmpq(ToOperand(instr->length()),
+ Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
} else {
__ cmpq(ToOperand(instr->length()), ToRegister(instr->index()));
}
@@ -3975,26 +3983,35 @@
ASSERT(!source.is(rcx));
ASSERT(!result.is(rcx));
+ // Only elements backing stores for non-COW arrays need to be copied.
+ Handle<FixedArrayBase> elements(object->elements());
+ bool has_elements = elements->length() > 0 &&
+ elements->map() != isolate()->heap()->fixed_cow_array_map();
+
// Increase the offset so that subsequent objects end up right after
- // this one.
- int current_offset = *offset;
- int size = object->map()->instance_size();
- *offset += size;
+ // this object and its backing store.
+ int object_offset = *offset;
+ int object_size = object->map()->instance_size();
+ int elements_offset = *offset + object_size;
+ int elements_size = has_elements ? elements->Size() : 0;
+ *offset += object_size + elements_size;
// Copy object header.
ASSERT(object->properties()->length() == 0);
- ASSERT(object->elements()->length() == 0 ||
- object->elements()->map() == isolate()->heap()->fixed_cow_array_map());
int inobject_properties = object->map()->inobject_properties();
- int header_size = size - inobject_properties * kPointerSize;
+ int header_size = object_size - inobject_properties * kPointerSize;
for (int i = 0; i < header_size; i += kPointerSize) {
- __ movq(rcx, FieldOperand(source, i));
- __ movq(FieldOperand(result, current_offset + i), rcx);
+ if (has_elements && i == JSObject::kElementsOffset) {
+ __ lea(rcx, Operand(result, elements_offset));
+ } else {
+ __ movq(rcx, FieldOperand(source, i));
+ }
+ __ movq(FieldOperand(result, object_offset + i), rcx);
}
// Copy in-object properties.
for (int i = 0; i < inobject_properties; i++) {
- int total_offset = current_offset + object->GetInObjectPropertyOffset(i);
+ int total_offset = object_offset + object->GetInObjectPropertyOffset(i);
Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i));
if (value->IsJSObject()) {
Handle<JSObject> value_object = Handle<JSObject>::cast(value);
@@ -4010,10 +4027,41 @@
__ movq(FieldOperand(result, total_offset), rcx);
}
}
+
+ // Copy elements backing store header.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ if (has_elements) {
+ __ LoadHeapObject(source, elements);
+ for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) {
+ __ movq(rcx, FieldOperand(source, i));
+ __ movq(FieldOperand(result, elements_offset + i), rcx);
+ }
+ }
+
+ // Copy elements backing store content.
+ ASSERT(!has_elements || elements->IsFixedArray());
+ int elements_length = has_elements ? elements->length() : 0;
+ for (int i = 0; i < elements_length; i++) {
+ int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i);
+ Handle<Object> value = JSObject::GetElement(object, i);
+ if (value->IsJSObject()) {
+ Handle<JSObject> value_object = Handle<JSObject>::cast(value);
+ __ lea(rcx, Operand(result, *offset));
+ __ movq(FieldOperand(result, total_offset), rcx);
+ __ LoadHeapObject(source, value_object);
+ EmitDeepCopy(value_object, result, source, offset);
+ } else if (value->IsHeapObject()) {
+ __ LoadHeapObject(rcx, Handle<HeapObject>::cast(value));
+ __ movq(FieldOperand(result, total_offset), rcx);
+ } else {
+ __ movq(rcx, value, RelocInfo::NONE);
+ __ movq(FieldOperand(result, total_offset), rcx);
+ }
+ }
}
-void LCodeGen::DoObjectLiteralFast(LObjectLiteralFast* instr) {
+void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
int size = instr->hydrogen()->total_size();
// Allocate all objects that are part of the literal in one big
@@ -4034,7 +4082,7 @@
}
-void LCodeGen::DoObjectLiteralGeneric(LObjectLiteralGeneric* instr) {
+void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
Handle<FixedArray> literals(instr->environment()->closure()->literals());
Handle<FixedArray> constant_properties =
instr->hydrogen()->constant_properties();
diff --git a/src/x64/lithium-gap-resolver-x64.cc b/src/x64/lithium-gap-resolver-x64.cc
index bf5d31d..877ea8c 100644
--- a/src/x64/lithium-gap-resolver-x64.cc
+++ b/src/x64/lithium-gap-resolver-x64.cc
@@ -204,8 +204,9 @@
ASSERT(destination->IsStackSlot());
Operand dst = cgen_->ToOperand(destination);
if (cgen_->IsInteger32Constant(constant_source)) {
- // Allow top 32 bits of an untagged Integer32 to be arbitrary.
- __ movl(dst, Immediate(cgen_->ToInteger32(constant_source)));
+ // Zero top 32 bits of a 64 bit spill slot that holds a 32 bit untagged
+ // value.
+ __ movq(dst, Immediate(cgen_->ToInteger32(constant_source)));
} else {
__ LoadObject(kScratchRegister, cgen_->ToHandle(constant_source));
__ movq(dst, kScratchRegister);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 9ffa8ae..3e30a4a 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -2094,19 +2094,18 @@
}
+LInstruction* LChunkBuilder::DoFastLiteral(HFastLiteral* instr) {
+ return MarkAsCall(DefineFixed(new LFastLiteral, rax), instr);
+}
+
+
LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
return MarkAsCall(DefineFixed(new LArrayLiteral, rax), instr);
}
-LInstruction* LChunkBuilder::DoObjectLiteralFast(HObjectLiteralFast* instr) {
- return MarkAsCall(DefineFixed(new LObjectLiteralFast, rax), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoObjectLiteralGeneric(
- HObjectLiteralGeneric* instr) {
- return MarkAsCall(DefineFixed(new LObjectLiteralGeneric, rax), instr);
+LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
+ return MarkAsCall(DefineFixed(new LObjectLiteral, rax), instr);
}
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index db11770..ccae35c 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -93,6 +93,7 @@
V(DivI) \
V(DoubleToI) \
V(ElementsKind) \
+ V(FastLiteral) \
V(FixedArrayBaseLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
@@ -135,8 +136,7 @@
V(NumberTagD) \
V(NumberTagI) \
V(NumberUntagD) \
- V(ObjectLiteralFast) \
- V(ObjectLiteralGeneric) \
+ V(ObjectLiteral) \
V(OsrEntry) \
V(OuterContext) \
V(Parameter) \
@@ -1906,6 +1906,13 @@
};
+class LFastLiteral: public LTemplateInstruction<1, 0, 0> {
+ public:
+ DECLARE_CONCRETE_INSTRUCTION(FastLiteral, "fast-literal")
+ DECLARE_HYDROGEN_ACCESSOR(FastLiteral)
+};
+
+
class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
@@ -1913,17 +1920,10 @@
};
-class LObjectLiteralFast: public LTemplateInstruction<1, 0, 0> {
+class LObjectLiteral: public LTemplateInstruction<1, 0, 0> {
public:
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralFast, "object-literal-fast")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralFast)
-};
-
-
-class LObjectLiteralGeneric: public LTemplateInstruction<1, 0, 0> {
- public:
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteralGeneric, "object-literal-generic")
- DECLARE_HYDROGEN_ACCESSOR(ObjectLiteralGeneric)
+ DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
+ DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
};
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index c070fb2..3ee3aad 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -2852,6 +2852,14 @@
}
+void MacroAssembler::AbortIfNotZeroExtended(Register int32_register) {
+ ASSERT(!int32_register.is(kScratchRegister));
+ movq(kScratchRegister, 0x100000000l, RelocInfo::NONE);
+ cmpq(kScratchRegister, int32_register);
+ Assert(above_equal, "32 bit value in register is not zero-extended");
+}
+
+
void MacroAssembler::AbortIfNotString(Register object) {
testb(object, Immediate(kSmiTagMask));
Assert(not_equal, "Operand is not a string");
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index aff496f..94b8584 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -949,6 +949,10 @@
void AbortIfNotSmi(Register object);
void AbortIfNotSmi(const Operand& object);
+ // Abort execution if a 64 bit register containing a 32 bit payload does not
+ // have zeros in the top 32 bits.
+ void AbortIfNotZeroExtended(Register reg);
+
// Abort execution if argument is a string. Used in debug code.
void AbortIfNotString(Register object);
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 121b282..2de0afb 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -52,9 +52,6 @@
# We do not yet shrink weak maps after they have been emptied by the GC
test-weakmaps/Shrinking: FAIL
-# BUG(1952): Temporarily disabled until issue is fixed.
-test-api/TurnOnAccessCheckAndRecompile: PASS || FAIL
-
##############################################################################
[ $arch == arm ]
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 817479f..8cd73f2 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -11050,27 +11050,27 @@
}
-v8::Handle<v8::String> a;
-v8::Handle<v8::String> h;
+static const char* kPropertyA = "a";
+static const char* kPropertyH = "h";
static bool NamedGetAccessBlockAandH(Local<v8::Object> obj,
Local<Value> name,
v8::AccessType type,
Local<Value> data) {
- return !(name->Equals(a) || name->Equals(h));
+ if (!name->IsString()) return false;
+ i::Handle<i::String> name_handle =
+ v8::Utils::OpenHandle(String::Cast(*name));
+ return !name_handle->IsEqualTo(i::CStrVector(kPropertyA))
+ && !name_handle->IsEqualTo(i::CStrVector(kPropertyH));
}
-// TODO(1952): Enable this test for threading test once the underlying bug is
-// fixed.
-TEST(TurnOnAccessCheckAndRecompile) {
+THREADED_TEST(TurnOnAccessCheckAndRecompile) {
v8::HandleScope handle_scope;
// Create an environment with access check to the global object disabled by
// default. When the registered access checker will block access to properties
- // a and h
- a = v8_str("a");
- h = v8_str("h");
+ // a and h.
v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
global_template->SetAccessCheckCallbacks(NamedGetAccessBlockAandH,
IndexedGetAccessBlocker,
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index d66f094..783c36d 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -4222,9 +4222,9 @@
// Get mirrors for the three objects with interceptor.
CompileRun(
- "named_mirror = debug.MakeMirror(intercepted_named);"
- "indexed_mirror = debug.MakeMirror(intercepted_indexed);"
- "both_mirror = debug.MakeMirror(intercepted_both)");
+ "var named_mirror = debug.MakeMirror(intercepted_named);"
+ "var indexed_mirror = debug.MakeMirror(intercepted_indexed);"
+ "var both_mirror = debug.MakeMirror(intercepted_both)");
CHECK(CompileRun(
"named_mirror instanceof debug.ObjectMirror")->BooleanValue());
CHECK(CompileRun(
@@ -4265,7 +4265,7 @@
CHECK_EQ(5, CompileRun(source)->Int32Value());
// Get the interceptor properties for the object with only named interceptor.
- CompileRun("named_values = named_mirror.properties()");
+ CompileRun("var named_values = named_mirror.properties()");
// Check that the properties are interceptor properties.
for (int i = 0; i < 3; i++) {
@@ -4284,7 +4284,7 @@
// Get the interceptor properties for the object with only indexed
// interceptor.
- CompileRun("indexed_values = indexed_mirror.properties()");
+ CompileRun("var indexed_values = indexed_mirror.properties()");
// Check that the properties are interceptor properties.
for (int i = 0; i < 2; i++) {
@@ -4296,7 +4296,7 @@
// Get the interceptor properties for the object with both types of
// interceptors.
- CompileRun("both_values = both_mirror.properties()");
+ CompileRun("var both_values = both_mirror.properties()");
// Check that the properties are interceptor properties.
for (int i = 0; i < 5; i++) {
@@ -4352,10 +4352,10 @@
// Get mirrors for the four objects.
CompileRun(
- "o0_mirror = debug.MakeMirror(o0);"
- "o1_mirror = debug.MakeMirror(o1);"
- "o2_mirror = debug.MakeMirror(o2);"
- "o3_mirror = debug.MakeMirror(o3)");
+ "var o0_mirror = debug.MakeMirror(o0);"
+ "var o1_mirror = debug.MakeMirror(o1);"
+ "var o2_mirror = debug.MakeMirror(o2);"
+ "var o3_mirror = debug.MakeMirror(o3)");
CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue());
CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue());
CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue());
@@ -4441,11 +4441,11 @@
CHECK_EQ(10, CompileRun("instance.x")->Int32Value());
// Get mirror for the object with property getter.
- CompileRun("instance_mirror = debug.MakeMirror(instance);");
+ CompileRun("var instance_mirror = debug.MakeMirror(instance);");
CHECK(CompileRun(
"instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
- CompileRun("named_names = instance_mirror.propertyNames();");
+ CompileRun("var named_names = instance_mirror.propertyNames();");
CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
CHECK(CompileRun(
@@ -4477,7 +4477,7 @@
env->Global()->Set(v8::String::New("instance"), named->NewInstance());
// Get mirror for the object with property getter.
- CompileRun("instance_mirror = debug.MakeMirror(instance);");
+ CompileRun("var instance_mirror = debug.MakeMirror(instance);");
CHECK(CompileRun(
"instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
CompileRun("named_names = instance_mirror.propertyNames();");
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 3070e16..d941d0f 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -449,6 +449,7 @@
case 0xA0:
case 0x2028:
case 0x2029:
+ case 0xFEFF:
return true;
default:
return unibrow::Space::Is(c);
diff --git a/test/mjsunit/builtins.js b/test/mjsunit/builtins.js
index f2ad544..e43b589 100644
--- a/test/mjsunit/builtins.js
+++ b/test/mjsunit/builtins.js
@@ -27,8 +27,7 @@
// Flags: --expose-natives-as=builtins
-// Checks that all function properties of the builtin object are neither
-// writable nor configurable. Also, theose functions that are actually
+// Checks that all function properties of the builtin object that are actually
// constructors (recognized by having properties on their .prototype object),
// have only unconfigurable properties on the prototype, and the methods
// are also non-writable.
@@ -75,8 +74,6 @@
assertTrue(desc.hasOwnProperty("value"));
var value = desc.value;
if (isFunction(value)) {
- assertFalse(desc.writable, name);
- assertFalse(desc.configurable, name);
checkConstructor(value, name);
}
}
diff --git a/test/mjsunit/compiler/inline-literals.js b/test/mjsunit/compiler/inline-literals.js
index 33d15f5..f78abe8 100644
--- a/test/mjsunit/compiler/inline-literals.js
+++ b/test/mjsunit/compiler/inline-literals.js
@@ -45,26 +45,6 @@
TestObjectLiteral(1, 2, 3);
TestObjectLiteral(1, 2, 3);
-%OptimizeFunctionOnNextCall(o1);
+%OptimizeFunctionOnNextCall(TestObjectLiteral);
TestObjectLiteral(1, 2, 3);
TestObjectLiteral('a', 'b', 'c');
-
-function f2() {
- return function(b, c) { return b + c; };
-}
-
-function f1(a, b, c) {
- return a + f2()(b, c);
-}
-
-function TestFunctionLiteral(a, b, c) {
- var expected = a + b + c;
- var result = f1(a, b, c);
- assertEquals(expected, result, "TestFunctionLiteral");
-}
-
-TestFunctionLiteral(1, 2, 3);
-TestFunctionLiteral(1, 2, 3);
-%OptimizeFunctionOnNextCall(f1);
-TestFunctionLiteral(1, 2, 3);
-TestFunctionLiteral('a', 'b', 'c');
diff --git a/test/mjsunit/compiler/literals-optimized.js b/test/mjsunit/compiler/literals-optimized.js
new file mode 100644
index 0000000..049e21a
--- /dev/null
+++ b/test/mjsunit/compiler/literals-optimized.js
@@ -0,0 +1,121 @@
+// Copyright 2012 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.
+
+// Flags: --allow-natives-syntax
+
+// Test optimized versions of array and object literals.
+
+function TestOptimizedLiteral(create, verify) {
+ verify(create(1, 2, 3), 1, 2, 3);
+ verify(create(3, 5, 7), 3, 5, 7);
+ %OptimizeFunctionOnNextCall(create);
+ verify(create(11, 23, 42), 11, 23, 42);
+}
+
+
+// Test shallow array literal.
+function create_arr_shallow(a, b, c) {
+ return [0, a, 0, b, 0, c];
+}
+function verify_arr_shallow(array, a, b, c) {
+ assertSame(6, array.length);
+ assertSame(0, array[0]);
+ assertSame(a, array[1]);
+ assertSame(0, array[2]);
+ assertSame(b, array[3]);
+ assertSame(0, array[4]);
+ assertSame(c, array[5]);
+}
+TestOptimizedLiteral(create_arr_shallow, verify_arr_shallow);
+
+
+// Test nested array literal.
+function create_arr_nested(a, b, c) {
+ return [[0, a], [b, c], [1, 2], 3];
+}
+function verify_arr_nested(array, a, b, c) {
+ assertSame(4, array.length);
+ assertSame(2, array[0].length);
+ assertSame(0, array[0][0]);
+ assertSame(a, array[0][1]);
+ assertSame(2, array[1].length);
+ assertSame(b, array[1][0]);
+ assertSame(c, array[1][1]);
+ assertSame(2, array[2].length);
+ assertSame(1, array[2][0]);
+ assertSame(2, array[2][1]);
+ assertSame(3, array[3]);
+}
+TestOptimizedLiteral(create_arr_nested, verify_arr_nested);
+
+
+// Test shallow object literal.
+function create_obj_shallow(a, b, c) {
+ return { x:a, y:b, z:c, v:'foo', 9:'bar' };
+}
+function verify_obj_shallow(object, a, b, c) {
+ assertSame(a, object.x);
+ assertSame(b, object.y);
+ assertSame(c, object.z);
+ assertSame('foo', object.v);
+ assertSame('bar', object[9]);
+}
+TestOptimizedLiteral(create_obj_shallow, verify_obj_shallow);
+
+
+// Test nested object literal.
+function create_obj_nested(a, b, c) {
+ return { x:{ v:a, w:b }, y:{ v:1, w:2 }, z:c, v:'foo', 9:'bar' };
+}
+function verify_obj_nested(object, a, b, c) {
+ assertSame(a, object.x.v);
+ assertSame(b, object.x.w);
+ assertSame(1, object.y.v);
+ assertSame(2, object.y.w);
+ assertSame(c, object.z);
+ assertSame('foo', object.v);
+ assertSame('bar', object[9]);
+}
+TestOptimizedLiteral(create_obj_nested, verify_obj_nested);
+
+
+// Test mixed array and object literal.
+function create_mixed_nested(a, b, c) {
+ return { x:[1, 2], y:[a, b], z:c, v:{ v:'foo' }, 9:'bar' };
+}
+function verify_mixed_nested(object, a, b, c) {
+ assertSame(2, object.x.length);
+ assertSame(1, object.x[0]);
+ assertSame(2, object.x[1]);
+ assertSame(2, object.y.length);
+ assertSame(a, object.y[0]);
+ assertSame(b, object.y[1]);
+ assertSame(c, object.z);
+ assertSame('foo', object.v.v);
+ assertSame('bar', object[9]);
+}
+TestOptimizedLiteral(create_mixed_nested, verify_mixed_nested);
diff --git a/test/mjsunit/elements-transition-hoisting.js b/test/mjsunit/elements-transition-hoisting.js
index 76f7b82..5e78f10 100644
--- a/test/mjsunit/elements-transition-hoisting.js
+++ b/test/mjsunit/elements-transition-hoisting.js
@@ -170,4 +170,42 @@
testHoistingWithSideEffect(new Array(5));
testHoistingWithSideEffect(new Array(5));
assertTrue(2 != %GetOptimizationStatus(testHoistingWithSideEffect));
+
+ function testStraightLineDupeElinination(a,b,c,d,e,f) {
+ var count = 3;
+ do {
+ assertTrue(true);
+ a[0] = b;
+ a[1] = c;
+ a[2] = d;
+ assertTrue(true);
+ a[3] = e; // TransitionElementsKind should be eliminated despite call.
+ a[4] = f;
+ } while (--count > 3);
+ }
+
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,0,.5);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,0,.5);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(5),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,0,.5);
+ testStraightLineDupeElinination(new Array(5),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,0,.5);
+ %OptimizeFunctionOnNextCall(testStraightLineDupeElinination);
+ testStraightLineDupeElinination(new Array(5));
+ testStraightLineDupeElinination(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testStraightLineDupeElinination));
}
diff --git a/test/mjsunit/harmony/module-parsing.js b/test/mjsunit/harmony/module-parsing.js
new file mode 100644
index 0000000..ac39863
--- /dev/null
+++ b/test/mjsunit/harmony/module-parsing.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.
+
+// Flags: --harmony-modules
+
+// Test basic module syntax, with and without ASI.
+
+module A {}
+
+module A1 = A
+module A2 = A;
+module A3 = A2
+
+module B {
+ var x
+ var x, y;
+ var x = 0, y
+ let x, y
+ let z = 1
+ const c = 9
+ function f() {}
+ module C {
+ let x
+ module D {}
+ let y
+ }
+ let zz = ""
+}
+
+module C1 = B.C;
+module D1 = B.C.D
+module D2 = C1.D
+module D3 = D2
+
+module E1 at "http://where"
+module E2 at "http://where";
+module E3 = E1.F
+
+
+// Check that ASI does not interfere.
+
+module
+X
+{
+let x
+}
+
+module
+Y
+=
+X
+
+module
+Z
+at
+"file://local"
diff --git a/test/mjsunit/math-min-max.js b/test/mjsunit/math-min-max.js
index 7717b3b..e4fd313 100644
--- a/test/mjsunit/math-min-max.js
+++ b/test/mjsunit/math-min-max.js
@@ -146,6 +146,14 @@
// Double representation.
assertEquals(v0, Math.max(v0++, v9++));
assertEquals(v9, Math.min(v0++, v9++));
+ // Mixed representation.
+ assertEquals(v1, Math.min(v1++, v9++)); // int32, double
+ assertEquals(v0, Math.max(v0++, v2++)); // double, int32
+ assertEquals(v1, Math.min(v1++, v6)); // int32, tagged
+ assertEquals(v2, Math.max(v5, v2++)); // tagged, int32
+ assertEquals(v6, Math.min(v6, v9++)); // tagged, double
+ assertEquals(v0, Math.max(v0++, v5)); // double, tagged
+
// Minus zero.
assertEquals(Infinity, 1/Math.max(v7, v8));
assertEquals(-Infinity, 1/Math.min(v7, v8));
diff --git a/test/mjsunit/regexp.js b/test/mjsunit/regexp.js
index 3c4f883..76fa44b 100644
--- a/test/mjsunit/regexp.js
+++ b/test/mjsunit/regexp.js
@@ -127,6 +127,17 @@
assertTrue(/^[Z-\c-e]*$/.test("Z[\\cde"));
+// Test that we handle \s and \S correctly on special Unicode characters.
+re = /\s/;
+assertTrue(re.test("\u2028"));
+assertTrue(re.test("\u2029"));
+assertTrue(re.test("\uFEFF"));
+
+re = /\S/;
+assertFalse(re.test("\u2028"));
+assertFalse(re.test("\u2029"));
+assertFalse(re.test("\uFEFF"));
+
// Test that we handle \s and \S correctly inside some bizarre
// character classes.
re = /[\s-:]/;
diff --git a/test/mjsunit/regress/regress-1790.js b/test/mjsunit/regress/regress-1790.js
new file mode 100644
index 0000000..8848eea
--- /dev/null
+++ b/test/mjsunit/regress/regress-1790.js
@@ -0,0 +1,58 @@
+// Copyright 2012 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 checking that the sequence of element access in built-in
+// array functions is specification conform (i.e. [[HasProperty]] might return
+// bogus result after [[Get]] has been called).
+
+function CheckSequence(builtin, callback) {
+ var array = [1,2,3];
+ var callback_count = 0;
+ var callback_wrapper = function() {
+ callback_count++;
+ return callback()
+ }
+
+ // Define getter that will delete itself upon first invocation.
+ Object.defineProperty(array, '1', {
+ get: function () { delete array[1]; },
+ configurable: true
+ });
+
+ assertTrue(array.hasOwnProperty('1'));
+ builtin.apply(array, [callback_wrapper, 'argument']);
+ assertFalse(array.hasOwnProperty('1'));
+ assertEquals(3, callback_count);
+}
+
+CheckSequence(Array.prototype.every, function() { return true; });
+CheckSequence(Array.prototype.filter, function() { return true; });
+CheckSequence(Array.prototype.forEach, function() { return 0; });
+CheckSequence(Array.prototype.map, function() { return 0; });
+CheckSequence(Array.prototype.reduce, function() { return 0; });
+CheckSequence(Array.prototype.reduceRight, function() { return 0; });
+CheckSequence(Array.prototype.some, function() { return false; });
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index bc096d5..cc2925d 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -213,6 +213,10 @@
# builtin to have undefined as the receiver.
ecma/String/15.5.4.6-2: FAIL_OK
+# Fail because it expects String.prototype.split to distinguish whether
+# separator was undefined or not passed at all.
+ecma/String/15.5.4.8-2: FAIL_OK
+
# Fail because of toLowerCase and toUpperCase conversion.
ecma/String/15.5.4.11-2: FAIL_OK
ecma/String/15.5.4.11-5: FAIL_OK
diff --git a/test/sputnik/sputnik.status b/test/sputnik/sputnik.status
index a587a6d..a4c7d57 100644
--- a/test/sputnik/sputnik.status
+++ b/test/sputnik/sputnik.status
@@ -125,6 +125,13 @@
S15.5.4.11_D1.1_T1: PASS || FAIL_OK
S15.5.4.11_D1.1_T3: PASS || FAIL_OK
S12.6.4_D1: PASS || FAIL_OK
+S15.5.4.14_A1_T6: FAIL_OK
+S15.5.4.14_A1_T7: FAIL_OK
+S15.5.4.14_A1_T8: FAIL_OK
+S15.5.4.14_A1_T9: FAIL_OK
+S15.5.4.14_A2_T7: FAIL_OK
+S15.10.2.12_A1_T1: FAIL_OK
+S15.10.2.12_A2_T1: FAIL_OK
# We allow function declarations within statements
S12.6.2_A13_T1: FAIL_OK
@@ -189,7 +196,6 @@
S15.4.4.2_A2_T1: FAIL_OK
S15.4.4.3_A2_T1: FAIL_OK
-
##################### SKIPPED TESTS #####################
# These tests take a looong time to run in debug mode.
diff --git a/test/test262/README b/test/test262/README
index 094356f..dae1843 100644
--- a/test/test262/README
+++ b/test/test262/README
@@ -4,11 +4,11 @@
http://hg.ecmascript.org/tests/test262
-at revision 271 as 'data' in this directory. Using later version
+at revision 309 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 271 http://hg.ecmascript.org/tests/test262 data
+hg clone -r 309 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
diff --git a/test/test262/test262.status b/test/test262/test262.status
index 1da988e..db99c80 100644
--- a/test/test262/test262.status
+++ b/test/test262/test262.status
@@ -33,9 +33,6 @@
# '__proto__' should be treated as a normal property in JSON.
S15.12.2_A1: FAIL
-# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1196
-S8.7_A5_T2: FAIL
-
# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1624
S10.4.2.1_A1: FAIL
@@ -59,14 +56,6 @@
15.2.3.7-6-a-284: FAIL
15.2.3.7-6-a-285: FAIL
-# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1790
-15.4.4.22-9-9: FAIL
-
-# Invalid test cases (recent change adding var changes semantics)
-S8.3_A1_T1: FAIL
-S15.3_A3_T1: FAIL
-S15.3_A3_T3: FAIL
-
##################### DELIBERATE INCOMPATIBILITIES #####################
# We deliberately treat arguments to parseInt() with a leading zero as
@@ -80,9 +69,6 @@
S15.8.2.18_A7: PASS || FAIL_OK
S15.8.2.13_A23: PASS || FAIL_OK
-# Sputnik tests (r97) assume RegExp.prototype is an Object, not a RegExp.
-S15.10.6_A2: FAIL_OK
-
# We are silent in some regexp cases where the spec wants us to give
# errors, for compatibility.
S15.10.2.11_A1_T2: FAIL
@@ -90,15 +76,9 @@
# We are more lenient in which string character escapes we allow than
# the spec (7.8.4 p. 19) wants us to be. This is for compatibility.
-S7.8.4_A4.3_T3: FAIL_OK
-S7.8.4_A4.3_T4: FAIL_OK
-S7.8.4_A4.3_T5: FAIL_OK
-S7.8.4_A4.3_T6: FAIL_OK
S7.8.4_A6.1_T4: FAIL_OK
S7.8.4_A6.2_T1: FAIL_OK
S7.8.4_A6.2_T2: FAIL_OK
-S7.8.4_A6.4_T1: FAIL_OK
-S7.8.4_A6.4_T2: FAIL_OK
S7.8.4_A7.1_T4: FAIL_OK
S7.8.4_A7.2_T1: FAIL_OK
S7.8.4_A7.2_T2: FAIL_OK
@@ -106,102 +86,12 @@
S7.8.4_A7.2_T4: FAIL_OK
S7.8.4_A7.2_T5: FAIL_OK
S7.8.4_A7.2_T6: FAIL_OK
-S7.8.4_A7.4_T1: FAIL_OK
-S7.8.4_A7.4_T2: FAIL_OK
-
-# Sputnik expects unicode escape sequences in RegExp flags to be interpreted.
-# The specification requires them to be passed uninterpreted to the RegExp
-# constructor. We now implement that.
-S7.8.5_A3.1_T7: FAIL_OK
-S7.8.5_A3.1_T8: FAIL_OK
-S7.8.5_A3.1_T9: FAIL_OK
-
-# We allow some keywords to be used as identifiers.
-S7.5.3_A1.15: FAIL_OK
-S7.5.3_A1.18: FAIL_OK
-S7.5.3_A1.21: FAIL_OK
-S7.5.3_A1.22: FAIL_OK
-S7.5.3_A1.23: FAIL_OK
-S7.5.3_A1.24: FAIL_OK
-S7.5.3_A1.26: FAIL_OK
-
-# This checks for non-262 behavior
-S7.6_D1: PASS || FAIL_OK
-S7.6_D2: PASS || FAIL_OK
-S8.4_D1.1: PASS || FAIL_OK
-S8.4_D2.1: PASS || FAIL_OK
-S8.4_D2.2: PASS || FAIL_OK
-S8.4_D2.3: PASS || FAIL_OK
-S8.4_D2.4: PASS || FAIL_OK
-S8.4_D2.5: PASS || FAIL_OK
-S8.4_D2.6: PASS || FAIL_OK
-S8.4_D2.7: PASS || FAIL_OK
-S11.4.3_D1.2: PASS || FAIL_OK
-S12.6.4_A14_T1: PASS || FAIL_OK
-S12.6.4_D1: PASS || FAIL_OK
-S12.6.4_R1: PASS || FAIL_OK
-S12.6.4_R2: PASS || FAIL_OK
-S13.2_D1.2: PASS || FAIL_OK
-S13_D1_T1: PASS || FAIL_OK
-S14_D4_T3: PASS || FAIL_OK
-S14_D7: PASS || FAIL_OK
-S15.1.2.2_D1.2: PASS || FAIL_OK
-S15.5.2_D2: PASS || FAIL_OK
-S15.5.4.11_D1.1_T1: PASS || FAIL_OK
-S15.5.4.11_D1.1_T2: PASS || FAIL_OK
-S15.5.4.11_D1.1_T3: PASS || FAIL_OK
-S15.5.4.11_D1.1_T4: PASS || FAIL_OK
-
-# We allow function declarations within statements
-S12.6.2_A13_T1: FAIL_OK
-S12.6.2_A13_T2: FAIL_OK
-S12.6.4_A13_T1: FAIL_OK
-S12.6.4_A13_T2: FAIL_OK
-S15.3.4.2_A1_T1: FAIL_OK
# Linux and Mac defaults to extended 80 bit floating point format in the FPU.
# We follow the other major JS engines by keeping this default.
S8.5_A2.2: PASS, FAIL if $system == linux, FAIL if $system == macos
S8.5_A2.1: PASS, FAIL if $system == linux, FAIL if $system == macos
-############################# ES3 TESTS ################################
-# These tests check for ES3 semantics, and differ from ES5.
-# When we follow ES5 semantics, it's ok to fail the test.
-
-# Allow keywords as names of properties in object initialisers and
-# in dot-notation property access.
-S11.1.5_A4.1: FAIL_OK
-S11.1.5_A4.2: FAIL_OK
-
-# Calls builtins without an explicit receiver which means that
-# undefined is passed to the builtin. The tests expect the global
-# object to be passed which was true in ES3 but not in ES5.
-S11.1.1_A2: FAIL_OK
-S15.5.4.4_A1_T3: FAIL_OK
-S15.5.4.5_A1_T3: FAIL_OK
-S15.5.4.6_A1_T3: FAIL_OK
-S15.5.4.7_A1_T3: FAIL_OK
-S15.5.4.8_A1_T3: FAIL_OK
-S15.5.4.9_A1_T3: FAIL_OK
-S15.5.4.10_A1_T3: FAIL_OK
-S15.5.4.11_A1_T3: FAIL_OK
-S15.5.4.12_A1_T3: FAIL_OK
-S15.5.4.13_A1_T3: FAIL_OK
-S15.5.4.14_A1_T3: FAIL_OK
-S15.5.4.15_A1_T3: FAIL_OK
-
-# NaN, Infinity and undefined are read-only according to ES5.
-S15.1.1.1_A2_T1: FAIL_OK # NaN
-S15.1.1.1_A2_T2: FAIL_OK # NaN
-S15.1.1.2_A2_T1: FAIL_OK # Infinity
-# S15.1.1.2_A2_T2 would fail if it weren't bogus in r97. sputnik bug #45.
-S15.1.1.3_A2_T1: FAIL_OK # undefined
-S15.1.1.3_A2_T2: FAIL_OK # undefined
-
-# Array.prototype.to[Locale]String is generic in ES5.
-S15.4.4.2_A2_T1: FAIL_OK
-S15.4.4.3_A2_T1: FAIL_OK
-
############################ SKIPPED TESTS #############################
# These tests take a looong time to run in debug mode.
diff --git a/tools/gcmole/gcmole.cc b/tools/gcmole/gcmole.cc
index 71ba24a..38ee6e0 100644
--- a/tools/gcmole/gcmole.cc
+++ b/tools/gcmole/gcmole.cc
@@ -69,6 +69,21 @@
}
+static std::string EXTERNAL("EXTERNAL");
+static std::string STATE_TAG("enum v8::internal::StateTag");
+
+static bool IsExternalVMState(const clang::ValueDecl* var) {
+ const clang::EnumConstantDecl* enum_constant =
+ dyn_cast<clang::EnumConstantDecl>(var);
+ if (enum_constant != NULL && enum_constant->getNameAsString() == EXTERNAL) {
+ clang::QualType type = enum_constant->getType();
+ return (type.getAsString() == STATE_TAG);
+ }
+
+ return false;
+}
+
+
struct Resolver {
explicit Resolver(clang::ASTContext& ctx)
: ctx_(ctx), decl_ctx_(ctx.getTranslationUnitDecl()) {
@@ -121,6 +136,13 @@
return true;
}
+ virtual bool VisitDeclRefExpr(clang::DeclRefExpr* expr) {
+ // If function mentions EXTERNAL VMState add artificial garbage collection
+ // mark.
+ if (IsExternalVMState(expr->getDecl())) AddCallee("CollectGarbage");
+ return true;
+ }
+
void AnalyzeFunction(const clang::FunctionDecl* f) {
MangledName name;
if (InV8Namespace(f) && GetMangledName(ctx_, f, &name)) {
@@ -278,6 +300,10 @@
return reinterpret_cast<Environment*>(effect_ & ~kAllEffects);
}
+ static ExprEffect GC() {
+ return ExprEffect(kCausesGC, NULL);
+ }
+
private:
ExprEffect(int effect, Environment* env)
: effect_((effect & kAllEffects) |
@@ -790,6 +816,9 @@
ExprEffect Use(const clang::Expr* parent,
const clang::ValueDecl* var,
const Environment& env) {
+ if (IsExternalVMState(var)) {
+ return ExprEffect::GC();
+ }
return Use(parent, var->getType(), var->getNameAsString(), env);
}
diff --git a/tools/gcmole/gcmole.lua b/tools/gcmole/gcmole.lua
index f8d3b62..09db547 100644
--- a/tools/gcmole/gcmole.lua
+++ b/tools/gcmole/gcmole.lua
@@ -106,7 +106,6 @@
cfg.plugin_args,
cfg.triple,
cfg.arch_define)
-
for _, filename in ipairs(filenames) do
log("-- %s", filename)
local action = cmd_line .. " src/" .. filename .. " 2>&1"
@@ -218,7 +217,13 @@
-- Callsites of such functions are safe as long as they are properly
-- check return value and propagate the Failure to the caller.
-- It should be possible to extend GCMole to understand this.
- "Heap.*AllocateFunctionPrototype"
+ "Heap.*AllocateFunctionPrototype",
+
+ -- Ignore all StateTag methods.
+ "StateTag",
+
+ -- Ignore printing of elements transition.
+ "PrintElementsTransition"
};
local function AddCause(name, cause)