Version 3.5.1.
Fixed setting the readonly flag on the prototype property using the API call FunctionTemplate::SetPrototypeAttributes (issue 1539).
Changed the tools/test.py script to use d8 instead of shell for testing.
Fixed crash in ToBooleanStub when GC happens during invocation.
Enabled automatic unboxing of double arrays.
Performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@8751 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index e142366..70585e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2011-07-28: Version 3.5.1
+
+ Fixed setting the readonly flag on the prototype property using the
+ API call FunctionTemplate::SetPrototypeAttributes (issue 1539).
+
+ Changed the tools/test.py script to use d8 instead of shell for
+ testing.
+
+ Fixed crash in ToBooleanStub when GC happens during invocation.
+
+ Enabled automatic unboxing of double arrays.
+
+ Performance improvements on all platforms.
+
+
2011-07-25: Version 3.5.0
Implemented Object.prototype.{hasOwnProperty, propertyIsEnumerable} for
diff --git a/include/v8.h b/include/v8.h
index f4f81e4..fa59712 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2231,11 +2231,10 @@
void SetHiddenPrototype(bool value);
/**
- * Sets the property attributes of the 'prototype' property of functions
- * created from this FunctionTemplate. Can be any combination of ReadOnly,
- * DontEnum and DontDelete.
+ * Sets the ReadOnly flag in the attributes of the 'prototype' property
+ * of functions created from this FunctionTemplate to true.
*/
- void SetPrototypeAttributes(int attributes);
+ void ReadOnlyPrototype();
/**
* Returns true if the given object is an instance of this function
diff --git a/src/api.cc b/src/api.cc
index b0e9775..6b50f99 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -877,7 +877,6 @@
i::Handle<i::FunctionTemplateInfo> info) {
info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
info->set_flag(0);
- info->set_prototype_attributes(i::Smi::FromInt(v8::None));
}
@@ -1100,14 +1099,13 @@
}
-void FunctionTemplate::SetPrototypeAttributes(int attributes) {
+void FunctionTemplate::ReadOnlyPrototype() {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetPrototypeAttributes()")) {
return;
}
ENTER_V8(isolate);
- Utils::OpenHandle(this)->set_prototype_attributes(
- i::Smi::FromInt(attributes));
+ Utils::OpenHandle(this)->set_read_only_prototype(true);
}
diff --git a/src/apinatives.js b/src/apinatives.js
index 193863f..c00195d 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -73,14 +73,10 @@
if (name) %FunctionSetName(fun, name);
cache[serialNumber] = fun;
var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
- var attributes = %GetTemplateField(data, kApiPrototypeAttributesOffset);
- if (attributes != NONE) {
- %IgnoreAttributesAndSetProperty(
- fun, "prototype",
- prototype ? Instantiate(prototype) : {},
- attributes);
- } else {
- fun.prototype = prototype ? Instantiate(prototype) : {};
+ var flags = %GetTemplateField(data, kApiFlagOffset);
+ fun.prototype = prototype ? Instantiate(prototype) : {};
+ if (flags & (1 << kReadOnlyPrototypeBit)) {
+ %FunctionSetReadOnlyPrototype(fun);
}
%SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
var parent = %GetTemplateField(data, kApiParentTemplateOffset);
diff --git a/src/code-stubs.h b/src/code-stubs.h
index cfc0ab0..6527fde 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -922,6 +922,7 @@
explicit Types(byte bits) : set_(bits) {}
bool IsEmpty() const { return set_.IsEmpty(); }
+ bool IsAll() const { return ToByte() == ((1 << NUMBER_OF_TYPES) - 1); }
bool Contains(Type type) const { return set_.Contains(type); }
void Add(Type type) { set_.Add(type); }
byte ToByte() const { return set_.ToIntegral(); }
@@ -933,6 +934,9 @@
EnumSet<Type, byte> set_;
};
+ static Types no_types() { return Types(); }
+ static Types all_types() { return Types((1 << NUMBER_OF_TYPES) - 1); }
+
explicit ToBooleanStub(Register tos, Types types = Types())
: tos_(tos), types_(types) { }
diff --git a/src/d8.cc b/src/d8.cc
index 4917f7d..ac20374 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -199,7 +199,7 @@
printf(" ");
}
v8::String::Utf8Value str(args[i]);
- int n = fwrite(*str, sizeof(**str), str.length(), stdout);
+ int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
if (n != str.length()) {
printf("Error in fwrite\n");
exit(1);
@@ -231,7 +231,7 @@
do { // Repeat if the line ends with an escape '\'.
// fgets got an error. Just give up.
if (fgets(buffer, kBufferSize, stdin) == NULL) return Null();
- length = strlen(buffer);
+ length = static_cast<int>(strlen(buffer));
linebreak = (length > 1 && buffer[length-2] == '\\');
if (linebreak) buffer[length-2] = '\n';
accumulator = String::Concat(accumulator, String::New(buffer, length-1));
@@ -299,9 +299,12 @@
Persistent<Object> persistent_array = Persistent<Object>::New(array);
persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
persistent_array.MarkIndependent();
- array->SetIndexedPropertiesToExternalArrayData(data, type, length);
- array->Set(String::New("length"), Int32::New(length), ReadOnly);
- array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
+ array->SetIndexedPropertiesToExternalArrayData(data, type,
+ static_cast<int>(length));
+ array->Set(String::New("length"),
+ Int32::New(static_cast<int32_t>(length)), ReadOnly);
+ array->Set(String::New("BYTES_PER_ELEMENT"),
+ Int32::New(static_cast<int32_t>(element_size)));
return array;
}
@@ -790,7 +793,7 @@
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
- int read = fread(&chars[i], 1, size - i, file);
+ int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
i += read;
}
fclose(file);
@@ -981,7 +984,7 @@
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;) {
- int read = fread(&chars[i], 1, size - i, file);
+ int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
i += read;
}
fclose(file);
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 2db44c3..005c137 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -100,7 +100,7 @@
DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
// Flags for experimental implementation features.
-DEFINE_bool(unbox_double_arrays, false, "automatically unbox arrays of doubles")
+DEFINE_bool(unbox_double_arrays, true, "automatically unbox arrays of doubles")
// Flags for Crankshaft.
#ifdef V8_TARGET_ARCH_MIPS
diff --git a/src/heap-inl.h b/src/heap-inl.h
index b0b4fbe..b08655c 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -142,6 +142,11 @@
}
+MaybeObject* Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
+ return CopyFixedDoubleArrayWithMap(src, src->map());
+}
+
+
MaybeObject* Heap::AllocateRaw(int size_in_bytes,
AllocationSpace space,
AllocationSpace retry_space) {
diff --git a/src/heap.cc b/src/heap.cc
index 8dbda27..efdb549 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3388,17 +3388,22 @@
object_size);
}
- FixedArray* elements = FixedArray::cast(source->elements());
+ FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
FixedArray* properties = FixedArray::cast(source->properties());
// Update elements if necessary.
if (elements->length() > 0) {
Object* elem;
- { MaybeObject* maybe_elem =
- (elements->map() == fixed_cow_array_map()) ?
- elements : CopyFixedArray(elements);
+ { MaybeObject* maybe_elem;
+ if (elements->map() == fixed_cow_array_map()) {
+ maybe_elem = FixedArray::cast(elements);
+ } else if (source->HasFastDoubleElements()) {
+ maybe_elem = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
+ } else {
+ maybe_elem = CopyFixedArray(FixedArray::cast(elements));
+ }
if (!maybe_elem->ToObject(&elem)) return maybe_elem;
}
- JSObject::cast(clone)->set_elements(FixedArray::cast(elem));
+ JSObject::cast(clone)->set_elements(FixedArrayBase::cast(elem));
}
// Update properties if necessary.
if (properties->length() > 0) {
@@ -3757,6 +3762,23 @@
}
+MaybeObject* Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
+ Map* map) {
+ int len = src->length();
+ Object* obj;
+ { MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(len, NOT_TENURED);
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ }
+ HeapObject* dst = HeapObject::cast(obj);
+ dst->set_map(map);
+ CopyBlock(
+ dst->address() + FixedDoubleArray::kLengthOffset,
+ src->address() + FixedDoubleArray::kLengthOffset,
+ FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset);
+ return obj;
+}
+
+
MaybeObject* Heap::AllocateFixedArray(int length) {
ASSERT(length >= 0);
if (length == 0) return empty_fixed_array();
diff --git a/src/heap.h b/src/heap.h
index 6cd4f84..a7a24b0 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -617,6 +617,16 @@
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
MUST_USE_RESULT MaybeObject* CopyFixedArrayWithMap(FixedArray* src, Map* map);
+ // Make a copy of src and return it. Returns
+ // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+ MUST_USE_RESULT inline MaybeObject* CopyFixedDoubleArray(
+ FixedDoubleArray* src);
+
+ // Make a copy of src, set the map, and return the copy. Returns
+ // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+ MUST_USE_RESULT MaybeObject* CopyFixedDoubleArrayWithMap(
+ FixedDoubleArray* src, Map* map);
+
// Allocates a fixed array initialized with the hole values.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 6c316cd..2be2a03 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1230,6 +1230,30 @@
}
+Range* HShr::InferRange() {
+ if (right()->IsConstant()) {
+ HConstant* c = HConstant::cast(right());
+ if (c->HasInteger32Value()) {
+ int shift_count = c->Integer32Value() & 0x1f;
+ if (left()->range()->CanBeNegative()) {
+ // Only compute bounds if the result always fits into an int32.
+ return (shift_count >= 1)
+ ? new Range(0, static_cast<uint32_t>(0xffffffff) >> shift_count)
+ : new Range();
+ } else {
+ // For positive inputs we can use the >> operator.
+ Range* result = (left()->range() != NULL)
+ ? left()->range()->Copy()
+ : new Range();
+ result->Sar(c->Integer32Value());
+ return result;
+ }
+ }
+ }
+ return HValue::InferRange();
+}
+
+
Range* HShl::InferRange() {
if (right()->IsConstant()) {
HConstant* c = HConstant::cast(right());
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 9b7a95b..23c0ae6 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -184,6 +184,7 @@
V(InobjectFields) \
V(BackingStoreFields) \
V(ArrayElements) \
+ V(DoubleArrayElements) \
V(SpecializedArrayElements) \
V(GlobalVars) \
V(Maps) \
@@ -933,8 +934,12 @@
class HBranch: public HUnaryControlInstruction {
public:
- HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
- : HUnaryControlInstruction(value, true_target, false_target) {
+ HBranch(HValue* value,
+ HBasicBlock* true_target,
+ HBasicBlock* false_target,
+ ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
+ : HUnaryControlInstruction(value, true_target, false_target),
+ expected_input_types_(expected_input_types) {
ASSERT(true_target != NULL && false_target != NULL);
}
explicit HBranch(HValue* value)
@@ -945,7 +950,14 @@
return Representation::None();
}
+ ToBooleanStub::Types expected_input_types() const {
+ return expected_input_types_;
+ }
+
DECLARE_CONCRETE_INSTRUCTION(Branch)
+
+ private:
+ ToBooleanStub::Types expected_input_types_;
};
@@ -3060,6 +3072,7 @@
HShr(HValue* context, HValue* left, HValue* right)
: HBitwiseBinaryOperation(context, left, right) { }
+ virtual Range* InferRange();
virtual HType CalculateInferredType();
DECLARE_CONCRETE_INSTRUCTION(Shr)
@@ -3524,7 +3537,7 @@
SetOperandAt(0, elements);
SetOperandAt(1, key);
set_representation(Representation::Double());
- SetFlag(kDependsOnArrayElements);
+ SetFlag(kDependsOnDoubleArrayElements);
SetFlag(kUseGVN);
}
@@ -3742,7 +3755,7 @@
SetOperandAt(0, elements);
SetOperandAt(1, key);
SetOperandAt(2, val);
- SetFlag(kChangesArrayElements);
+ SetFlag(kChangesDoubleArrayElements);
}
virtual Representation RequiredInputRepresentation(int index) const {
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index d03aa5d..a6205ec 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -736,6 +736,8 @@
HPhase phase("Assign dominators", this);
for (int i = 0; i < blocks_.length(); ++i) {
if (blocks_[i]->IsLoopHeader()) {
+ // Only the first predecessor of a loop header is from outside the loop.
+ // All others are back edges, and thus cannot dominate the loop header.
blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->first());
} else {
for (int j = 0; j < blocks_[i]->predecessors()->length(); ++j) {
@@ -743,13 +745,15 @@
}
}
}
+}
- // Propagate flag marking blocks containing unconditional deoptimize.
+// Mark all blocks that are dominated by an unconditional soft deoptimize to
+// prevent code motion across those blocks.
+void HGraph::PropagateDeoptimizingMark() {
+ HPhase phase("Propagate deoptimizing mark", this);
MarkAsDeoptimizingRecursively(entry_block());
}
-
-// Mark all blocks that are dominated by an unconditional deoptimize.
void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) {
for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
HBasicBlock* dominated = block->dominated_blocks()->at(i);
@@ -2158,7 +2162,9 @@
}
HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
- HBranch* test = new(zone()) HBranch(value, empty_true, empty_false);
+ unsigned test_id = condition()->test_id();
+ ToBooleanStub::Types expected(builder->oracle()->ToBooleanTypes(test_id));
+ HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
builder->current_block()->Finish(test);
empty_true->Goto(if_true());
@@ -2293,6 +2299,7 @@
graph()->OrderBlocks();
graph()->AssignDominators();
+ graph()->PropagateDeoptimizingMark();
graph()->EliminateRedundantPhis();
if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
if (!graph()->CollectPhis()) {
@@ -5504,9 +5511,11 @@
// We need an extra block to maintain edge-split form.
HBasicBlock* empty_block = graph()->CreateBasicBlock();
HBasicBlock* eval_right = graph()->CreateBasicBlock();
+ unsigned test_id = expr->left()->test_id();
+ ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id));
HBranch* test = is_logical_and
- ? new(zone()) HBranch(Top(), eval_right, empty_block)
- : new(zone()) HBranch(Top(), empty_block, eval_right);
+ ? new(zone()) HBranch(Top(), eval_right, empty_block, expected)
+ : new(zone()) HBranch(Top(), empty_block, eval_right, expected);
current_block()->Finish(test);
set_current_block(eval_right);
diff --git a/src/hydrogen.h b/src/hydrogen.h
index c0d6323..e5dd8a9 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -238,7 +238,7 @@
void OrderBlocks();
void AssignDominators();
void ReplaceCheckedValues();
- void MarkAsDeoptimizingRecursively(HBasicBlock* block);
+ void PropagateDeoptimizingMark();
// Returns false if there are phi-uses of the arguments-object
// which are not supported by the optimizing compiler.
@@ -293,6 +293,7 @@
HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
Object* value);
+ void MarkAsDeoptimizingRecursively(HBasicBlock* block);
void InsertTypeConversions(HInstruction* instr);
void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi);
@@ -719,6 +720,8 @@
HBasicBlock* second,
int join_id);
+ TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
+
private:
// Type of a member function that generates inline code for a native function.
typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call);
@@ -747,7 +750,6 @@
CompilationInfo* info() const {
return function_state()->compilation_info();
}
- TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
AstContext* call_context() const {
return function_state()->call_context();
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 3a33c9e..cd2601e 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -348,8 +348,10 @@
__ ret(1 * kPointerSize);
}
- __ bind(&patch);
- GenerateTypeTransition(masm);
+ if (!types_.IsAll()) {
+ __ bind(&patch);
+ GenerateTypeTransition(masm);
+ }
}
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index f9f63a7..7d41d95 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -572,7 +572,7 @@
Label* fall_through) {
ToBooleanStub stub(result_register());
__ push(result_register());
- __ CallStub(&stub);
+ __ CallStub(&stub, condition->test_id());
__ test(result_register(), Operand(result_register()));
// The stub returns nonzero for true.
Split(not_zero, if_true, if_false, fall_through);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 7211ba4..6f99781 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1424,7 +1424,7 @@
// The conversion stub doesn't cause garbage collections so it's
// safe to not record a safepoint after the call.
__ bind(&call_stub);
- ToBooleanStub stub(eax);
+ ToBooleanStub stub(eax, ToBooleanStub::all_types());
__ pushad();
__ push(reg);
__ CallStub(&stub);
@@ -2232,7 +2232,6 @@
void LCodeGen::DoLoadKeyedFastDoubleElement(
LLoadKeyedFastDoubleElement* instr) {
- Register elements = ToRegister(instr->elements());
XMMRegister result = ToDoubleRegister(instr->result());
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3097,7 +3096,6 @@
void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) {
XMMRegister value = ToDoubleRegister(instr->value());
- Register elements = ToRegister(instr->elements());
Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
Label have_value;
diff --git a/src/json-parser.h b/src/json-parser.h
index 3ef5afb..f93b04d 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -166,7 +166,8 @@
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source) {
isolate_ = source->map()->isolate();
- source_ = Handle<String>(source->TryFlattenGetString());
+ FlattenString(source);
+ source_ = source;
source_length_ = source_->length();
// Optimized fast case where we only have ASCII characters.
diff --git a/src/macros.py b/src/macros.py
index fc08cb1..5ba7ac3 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -44,7 +44,7 @@
const kApiConstructorOffset = 2;
const kApiPrototypeTemplateOffset = 5;
const kApiParentTemplateOffset = 6;
-const kApiPrototypeAttributesOffset = 15;
+const kApiFlagOffset = 14;
const NO_HINT = 0;
const NUMBER_HINT = 1;
@@ -65,6 +65,7 @@
# For apinatives.js
const kUninitialized = -1;
+const kReadOnlyPrototypeBit = 3; # For FunctionTemplateInfo, matches objects.h
# Note: kDayZeroInJulianDay = ToJulianDay(1970, 0, 1).
const kInvalidDate = 'Invalid Date';
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 2417c32..53a3183 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1967,6 +1967,17 @@
template<typename Shape, typename Key>
+int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
+ const int kMinCapacity = 32;
+ int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
+ if (capacity < kMinCapacity) {
+ capacity = kMinCapacity; // Guarantee min capacity.
+ }
+ return capacity;
+}
+
+
+template<typename Shape, typename Key>
int HashTable<Shape, Key>::FindEntry(Key key) {
return FindEntry(GetIsolate(), key);
}
@@ -3268,8 +3279,6 @@
ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
kAccessCheckInfoOffset)
ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
-ACCESSORS(FunctionTemplateInfo, prototype_attributes, Smi,
- kPrototypeAttributesOffset)
ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
@@ -3324,6 +3333,8 @@
BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
kNeedsAccessCheckBit)
+BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
+ kReadOnlyPrototypeBit)
BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
kIsExpressionBit)
BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
diff --git a/src/objects.cc b/src/objects.cc
index 8e36ae5..a423ae4 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2471,6 +2471,9 @@
// callback setter removed. The two lines looking up the LookupResult
// result are also added. If one of the functions is changed, the other
// should be.
+// Note that this method cannot be used to set the prototype of a function
+// because ConvertDescriptorToField() which is called in "case CALLBACKS:"
+// doesn't handle function prototypes correctly.
MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
String* name,
Object* value,
@@ -2896,9 +2899,12 @@
int length = IsJSArray()
? Smi::cast(JSArray::cast(this)->length())->value()
: array->length();
+ int old_capacity = 0;
+ int used_elements = 0;
+ GetElementsCapacityAndUsage(&old_capacity, &used_elements);
NumberDictionary* dictionary = NULL;
{ Object* object;
- MaybeObject* maybe = NumberDictionary::Allocate(length);
+ MaybeObject* maybe = NumberDictionary::Allocate(used_elements);
if (!maybe->ToObject(&object)) return maybe;
dictionary = NumberDictionary::cast(object);
}
@@ -8615,7 +8621,7 @@
} else {
new_length = dictionary->max_number_key() + 1;
}
- MaybeObject* result = ShouldConvertToFastDoubleElements()
+ MaybeObject* result = CanConvertToFastDoubleElements()
? SetFastDoubleElementsCapacityAndLength(new_length, new_length)
: SetFastElementsCapacityAndLength(new_length, new_length);
if (result->IsFailure()) return result;
@@ -9157,7 +9163,15 @@
bool JSObject::HasDenseElements() {
int capacity = 0;
- int number_of_elements = 0;
+ int used = 0;
+ GetElementsCapacityAndUsage(&capacity, &used);
+ return (capacity == 0) || (used > (capacity / 2));
+}
+
+
+void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
+ *capacity = 0;
+ *used = 0;
FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
FixedArray* backing_store = NULL;
@@ -9168,34 +9182,33 @@
backing_store = FixedArray::cast(backing_store_base);
if (backing_store->IsDictionary()) {
NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
- capacity = dictionary->Capacity();
- number_of_elements = dictionary->NumberOfElements();
+ *capacity = dictionary->Capacity();
+ *used = dictionary->NumberOfElements();
break;
}
// Fall through.
case FAST_ELEMENTS:
backing_store = FixedArray::cast(backing_store_base);
- capacity = backing_store->length();
- for (int i = 0; i < capacity; ++i) {
- if (!backing_store->get(i)->IsTheHole()) ++number_of_elements;
+ *capacity = backing_store->length();
+ for (int i = 0; i < *capacity; ++i) {
+ if (!backing_store->get(i)->IsTheHole()) ++(*used);
}
break;
case DICTIONARY_ELEMENTS: {
NumberDictionary* dictionary =
NumberDictionary::cast(FixedArray::cast(elements()));
- capacity = dictionary->Capacity();
- number_of_elements = dictionary->NumberOfElements();
+ *capacity = dictionary->Capacity();
+ *used = dictionary->NumberOfElements();
break;
}
case FAST_DOUBLE_ELEMENTS: {
FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
- capacity = elms->length();
- for (int i = 0; i < capacity; i++) {
- if (!elms->is_the_hole(i)) number_of_elements++;
+ *capacity = elms->length();
+ for (int i = 0; i < *capacity; i++) {
+ if (!elms->is_the_hole(i)) ++(*used);
}
break;
}
- case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_BYTE_ELEMENTS:
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case EXTERNAL_SHORT_ELEMENTS:
@@ -9203,31 +9216,34 @@
case EXTERNAL_INT_ELEMENTS:
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case EXTERNAL_FLOAT_ELEMENTS:
- case EXTERNAL_DOUBLE_ELEMENTS: {
- return true;
- }
+ case EXTERNAL_DOUBLE_ELEMENTS:
+ case EXTERNAL_PIXEL_ELEMENTS:
+ // External arrays are considered 100% used.
+ ExternalArray* external_array = ExternalArray::cast(elements());
+ *capacity = external_array->length();
+ *used = external_array->length();
+ break;
}
- return (capacity == 0) || (number_of_elements > (capacity / 2));
}
bool JSObject::ShouldConvertToSlowElements(int new_capacity) {
- if (new_capacity <= kMaxFastElementsLength) return false;
- // Keep the array in fast case if the current backing storage is
- // almost filled and if the new capacity is no more than twice the
- // old capacity.
- int old_capacity = 0;
- if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) {
- FixedArray* backing_store = FixedArray::cast(elements());
- old_capacity = FixedArray::cast(backing_store->get(1))->length();
- } else if (HasFastElements()) {
- old_capacity = FixedArray::cast(elements())->length();
- } else if (HasFastDoubleElements()) {
- old_capacity = FixedDoubleArray::cast(elements())->length();
- } else {
- UNREACHABLE();
+ STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <=
+ kMaxUncheckedFastElementsLength);
+ if (new_capacity <= kMaxUncheckedOldFastElementsLength ||
+ (new_capacity <= kMaxUncheckedFastElementsLength &&
+ GetHeap()->InNewSpace(this))) {
+ return false;
}
- return !HasDenseElements() || ((new_capacity / 2) > old_capacity);
+ // If the fast-case backing storage takes up roughly three times as
+ // much space (in machine words) as a dictionary backing storage
+ // would, the object should have slow elements.
+ int old_capacity = 0;
+ int used_elements = 0;
+ GetElementsCapacityAndUsage(&old_capacity, &used_elements);
+ int dictionary_size = NumberDictionary::ComputeCapacity(used_elements) *
+ NumberDictionary::kEntrySize;
+ return 3 * dictionary_size <= new_capacity;
}
@@ -9250,20 +9266,21 @@
// dictionary, we cannot go back to fast case.
if (dictionary->requires_slow_elements()) return false;
// If the dictionary backing storage takes up roughly half as much
- // space as a fast-case backing storage would the array should have
- // fast elements.
- uint32_t length = 0;
+ // space (in machine words) as a fast-case backing storage would,
+ // the object should have fast elements.
+ uint32_t array_size = 0;
if (IsJSArray()) {
- CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
+ CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size));
} else {
- length = dictionary->max_number_key();
+ array_size = dictionary->max_number_key();
}
- return static_cast<uint32_t>(dictionary->Capacity()) >=
- (length / (2 * NumberDictionary::kEntrySize));
+ uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
+ NumberDictionary::kEntrySize;
+ return 2 * dictionary_size >= array_size;
}
-bool JSObject::ShouldConvertToFastDoubleElements() {
+bool JSObject::CanConvertToFastDoubleElements() {
if (FLAG_unbox_double_arrays) {
ASSERT(HasDictionaryElements());
NumberDictionary* dictionary = NumberDictionary::cast(elements());
@@ -10194,11 +10211,8 @@
template<typename Shape, typename Key>
MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for,
PretenureFlag pretenure) {
- const int kMinCapacity = 32;
- int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
- if (capacity < kMinCapacity) {
- capacity = kMinCapacity; // Guarantee min capacity.
- } else if (capacity > HashTable::kMaxCapacity) {
+ int capacity = ComputeCapacity(at_least_space_for);
+ if (capacity > HashTable::kMaxCapacity) {
return Failure::OutOfMemoryException();
}
diff --git a/src/objects.h b/src/objects.h
index 8993728..9ef14db 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1654,7 +1654,7 @@
bool ShouldConvertToFastElements();
// Returns true if the elements of JSObject contains only values that can be
// represented in a FixedDoubleArray.
- bool ShouldConvertToFastDoubleElements();
+ bool CanConvertToFastDoubleElements();
// Tells whether the index'th element is present.
inline bool HasElement(uint32_t index);
@@ -1948,8 +1948,21 @@
// Also maximal value of JSArray's length property.
static const uint32_t kMaxElementCount = 0xffffffffu;
+ // Constants for heuristics controlling conversion of fast elements
+ // to slow elements.
+
+ // Maximal gap that can be introduced by adding an element beyond
+ // the current elements length.
static const uint32_t kMaxGap = 1024;
- static const int kMaxFastElementsLength = 5000;
+
+ // Maximal length of fast elements array that won't be checked for
+ // being dense enough on expansion.
+ static const int kMaxUncheckedFastElementsLength = 5000;
+
+ // Same as above but for old arrays. This limit is more strict. We
+ // don't want to be wasteful with long lived objects.
+ static const int kMaxUncheckedOldFastElementsLength = 500;
+
static const int kInitialMaxFastElementArray = 100000;
static const int kMaxFastProperties = 12;
static const int kMaxInstanceSize = 255 * kPointerSize;
@@ -2015,6 +2028,9 @@
// Returns true if most of the elements backing storage is used.
bool HasDenseElements();
+ // Gets the current elements capacity and the number of used elements.
+ void GetElementsCapacityAndUsage(int* capacity, int* used);
+
bool CanSetCallback(String* name);
MUST_USE_RESULT MaybeObject* SetElementCallback(
uint32_t index,
@@ -2491,6 +2507,10 @@
int at_least_space_for,
PretenureFlag pretenure = NOT_TENURED);
+ // Computes the required capacity for a table holding the given
+ // number of elements. May be more than HashTable::kMaxCapacity.
+ static int ComputeCapacity(int at_least_space_for);
+
// Returns the key at entry.
Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
@@ -6846,7 +6866,6 @@
DECL_ACCESSORS(instance_call_handler, Object)
DECL_ACCESSORS(access_check_info, Object)
DECL_ACCESSORS(flag, Smi)
- DECL_ACCESSORS(prototype_attributes, Smi)
// Following properties use flag bits.
DECL_BOOLEAN_ACCESSORS(hidden_prototype)
@@ -6854,6 +6873,7 @@
// If the bit is set, object instances created by this function
// requires access check.
DECL_BOOLEAN_ACCESSORS(needs_access_check)
+ DECL_BOOLEAN_ACCESSORS(read_only_prototype)
static inline FunctionTemplateInfo* cast(Object* obj);
@@ -6886,14 +6906,14 @@
static const int kAccessCheckInfoOffset =
kInstanceCallHandlerOffset + kPointerSize;
static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
- static const int kPrototypeAttributesOffset = kFlagOffset + kPointerSize;
- static const int kSize = kPrototypeAttributesOffset + kPointerSize;
+ static const int kSize = kFlagOffset + kPointerSize;
private:
// Bit position in the flag, from least significant bit position.
static const int kHiddenPrototypeBit = 0;
static const int kUndetectableBit = 1;
static const int kNeedsAccessCheckBit = 2;
+ static const int kReadOnlyPrototypeBit = 3;
DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
};
diff --git a/src/runtime.cc b/src/runtime.cc
index f0cb75a..df225b6 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -219,8 +219,20 @@
}
break;
}
- default:
- UNREACHABLE();
+ case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+ UNIMPLEMENTED();
+ break;
+ case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+ case JSObject::EXTERNAL_BYTE_ELEMENTS:
+ case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+ case JSObject::EXTERNAL_SHORT_ELEMENTS:
+ case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+ case JSObject::EXTERNAL_INT_ELEMENTS:
+ case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+ case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+ case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+ case JSObject::FAST_DOUBLE_ELEMENTS:
+ // No contained objects, nothing to do.
break;
}
return copy;
@@ -1666,7 +1678,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
ASSERT(args.length() == 3);
CONVERT_SMI_ARG_CHECKED(elements_count, 0);
- if (elements_count > JSArray::kMaxFastElementsLength) {
+ if (elements_count < 0 ||
+ elements_count > FixedArray::kMaxLength ||
+ !Smi::IsValid(elements_count)) {
return isolate->ThrowIllegalOperation();
}
Object* new_object;
@@ -1968,6 +1982,61 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
+ NoHandleAllocation ha;
+ RUNTIME_ASSERT(args.length() == 1);
+ CONVERT_CHECKED(JSFunction, function, args[0]);
+
+ MaybeObject* maybe_name =
+ isolate->heap()->AllocateStringFromAscii(CStrVector("prototype"));
+ String* name;
+ if (!maybe_name->To(&name)) return maybe_name;
+
+ if (function->HasFastProperties()) {
+ // Construct a new field descriptor with updated attributes.
+ DescriptorArray* instance_desc = function->map()->instance_descriptors();
+ int index = instance_desc->Search(name);
+ ASSERT(index != DescriptorArray::kNotFound);
+ PropertyDetails details(instance_desc->GetDetails(index));
+ CallbacksDescriptor new_desc(name,
+ instance_desc->GetValue(index),
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
+ details.index());
+ // Construct a new field descriptors array containing the new descriptor.
+ Object* descriptors_unchecked;
+ { MaybeObject* maybe_descriptors_unchecked =
+ instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS);
+ if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
+ return maybe_descriptors_unchecked;
+ }
+ }
+ DescriptorArray* new_descriptors =
+ DescriptorArray::cast(descriptors_unchecked);
+ // Create a new map featuring the new field descriptors array.
+ Object* map_unchecked;
+ { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors();
+ if (!maybe_map_unchecked->ToObject(&map_unchecked)) {
+ return maybe_map_unchecked;
+ }
+ }
+ Map* new_map = Map::cast(map_unchecked);
+ new_map->set_instance_descriptors(new_descriptors);
+ function->set_map(new_map);
+ } else { // Dictionary properties.
+ // Directly manipulate the property details.
+ int entry = function->property_dictionary()->FindEntry(name);
+ ASSERT(entry != StringDictionary::kNotFound);
+ PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
+ PropertyDetails new_details(
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
+ details.type(),
+ details.index());
+ function->property_dictionary()->DetailsAtPut(entry, new_details);
+ }
+ return function;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
diff --git a/src/runtime.h b/src/runtime.h
index ac912d8..a42b3bc 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -210,6 +210,7 @@
F(FunctionSetInstanceClassName, 2, 1) \
F(FunctionSetLength, 2, 1) \
F(FunctionSetPrototype, 2, 1) \
+ F(FunctionSetReadOnlyPrototype, 1, 1) \
F(FunctionGetName, 1, 1) \
F(FunctionSetName, 2, 1) \
F(FunctionSetBound, 1, 1) \
diff --git a/src/type-info.cc b/src/type-info.cc
index defb1ae..e10c5f4 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -439,6 +439,12 @@
}
+byte TypeFeedbackOracle::ToBooleanTypes(unsigned ast_id) {
+ Handle<Object> object = GetInfo(ast_id);
+ return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
+}
+
+
// Things are a bit tricky here: The iterator for the RelocInfos and the infos
// themselves are not GC-safe, so we first get all infos, then we create the
// dictionary (possibly triggering GC), and finally we relocate the collected
@@ -523,6 +529,7 @@
case Code::UNARY_OP_IC:
case Code::BINARY_OP_IC:
case Code::COMPARE_IC:
+ case Code::TO_BOOLEAN_IC:
SetInfo(ast_id, target);
break;
diff --git a/src/type-info.h b/src/type-info.h
index 0a8c935..dee4c34 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -238,6 +238,11 @@
bool LoadIsBuiltin(Property* expr, Builtins::Name id);
+ // TODO(1571) We can't use ToBooleanStub::Types as the return value because
+ // of various cylces in our headers. Death to tons of implementations in
+ // headers!! :-P
+ byte ToBooleanTypes(unsigned ast_id);
+
// Get type information for arithmetic operations and compares.
TypeInfo UnaryType(UnaryOperation* expr);
TypeInfo BinaryType(BinaryOperation* expr);
diff --git a/src/version.cc b/src/version.cc
index 53d542e..eac99e2 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 5
-#define BUILD_NUMBER 0
+#define BUILD_NUMBER 1
#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/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 49361e4..667d781 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -2246,7 +2246,6 @@
void LCodeGen::DoLoadKeyedFastDoubleElement(
LLoadKeyedFastDoubleElement* instr) {
- Register elements = ToRegister(instr->elements());
XMMRegister result(ToDoubleRegister(instr->result()));
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3101,14 +3100,11 @@
void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) {
XMMRegister value = ToDoubleRegister(instr->value());
- Register elements = ToRegister(instr->elements());
Label have_value;
__ ucomisd(value, value);
__ j(parity_odd, &have_value); // NaN.
- ExternalReference canonical_nan_reference =
- ExternalReference::address_of_canonical_non_hole_nan();
__ Set(kScratchRegister, BitCast<uint64_t>(
FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
__ movq(value, kScratchRegister);
diff --git a/test/benchmarks/testcfg.py b/test/benchmarks/testcfg.py
index 51d8520..ab9d40f 100644
--- a/test/benchmarks/testcfg.py
+++ b/test/benchmarks/testcfg.py
@@ -91,7 +91,7 @@
return [test]
def GetBuildRequirements(self):
- return ['sample', 'sample=shell']
+ return ['d8']
def GetTestStatus(self, sections, defs):
pass
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index eb9edd2..ed01532 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -7055,53 +7055,34 @@
}
-THREADED_TEST(SetPrototypeProperties) {
+THREADED_TEST(FunctionReadOnlyPrototype) {
v8::HandleScope handle_scope;
LocalContext context;
Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
- t1->SetPrototypeAttributes(v8::DontDelete);
+ t1->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(42));
+ t1->ReadOnlyPrototype();
context->Global()->Set(v8_str("func1"), t1->GetFunction());
+ // Configured value of ReadOnly flag.
CHECK(CompileRun(
"(function() {"
" descriptor = Object.getOwnPropertyDescriptor(func1, 'prototype');"
- " return (descriptor['writable'] == true) &&"
- " (descriptor['enumerable'] == true) &&"
- " (descriptor['configurable'] == false);"
+ " return (descriptor['writable'] == false);"
"})()")->BooleanValue());
+ CHECK_EQ(42, CompileRun("func1.prototype.x")->Int32Value());
+ CHECK_EQ(42,
+ CompileRun("func1.prototype = {}; func1.prototype.x")->Int32Value());
Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
- t2->SetPrototypeAttributes(v8::DontEnum);
+ t2->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(42));
context->Global()->Set(v8_str("func2"), t2->GetFunction());
+ // Default value of ReadOnly flag.
CHECK(CompileRun(
"(function() {"
" descriptor = Object.getOwnPropertyDescriptor(func2, 'prototype');"
- " return (descriptor['writable'] == true) &&"
- " (descriptor['enumerable'] == false) &&"
- " (descriptor['configurable'] == true);"
+ " return (descriptor['writable'] == true);"
"})()")->BooleanValue());
-
- Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
- t3->SetPrototypeAttributes(v8::ReadOnly);
- context->Global()->Set(v8_str("func3"), t3->GetFunction());
- CHECK(CompileRun(
- "(function() {"
- " descriptor = Object.getOwnPropertyDescriptor(func3, 'prototype');"
- " return (descriptor['writable'] == false) &&"
- " (descriptor['enumerable'] == true) &&"
- " (descriptor['configurable'] == true);"
- "})()")->BooleanValue());
-
- Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
- t4->SetPrototypeAttributes(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
- context->Global()->Set(v8_str("func4"), t4->GetFunction());
- CHECK(CompileRun(
- "(function() {"
- " descriptor = Object.getOwnPropertyDescriptor(func4, 'prototype');"
- " return (descriptor['writable'] == false) &&"
- " (descriptor['enumerable'] == false) &&"
- " (descriptor['configurable'] == false);"
- "})()")->BooleanValue());
+ CHECK_EQ(42, CompileRun("func2.prototype.x")->Int32Value());
}
diff --git a/test/es5conform/testcfg.py b/test/es5conform/testcfg.py
index af74b8c..b6a17d9 100644
--- a/test/es5conform/testcfg.py
+++ b/test/es5conform/testcfg.py
@@ -97,7 +97,7 @@
return tests
def GetBuildRequirements(self):
- return ['sample', 'sample=shell']
+ return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'es5conform.status')
diff --git a/test/message/testcfg.py b/test/message/testcfg.py
index aabbfef..af467e6 100644
--- a/test/message/testcfg.py
+++ b/test/message/testcfg.py
@@ -125,7 +125,7 @@
return result
def GetBuildRequirements(self):
- return ['sample', 'sample=shell']
+ return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'message.status')
diff --git a/test/mjsunit/testcfg.py b/test/mjsunit/testcfg.py
index 7c6311b..87ed4fae 100644
--- a/test/mjsunit/testcfg.py
+++ b/test/mjsunit/testcfg.py
@@ -145,7 +145,7 @@
return result
def GetBuildRequirements(self):
- return ['sample', 'sample=shell']
+ return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'mjsunit.status')
diff --git a/test/mozilla/testcfg.py b/test/mozilla/testcfg.py
index 3728f79..587781d 100644
--- a/test/mozilla/testcfg.py
+++ b/test/mozilla/testcfg.py
@@ -125,7 +125,7 @@
return tests
def GetBuildRequirements(self):
- return ['sample', 'sample=shell']
+ return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'mozilla.status')
diff --git a/test/sputnik/testcfg.py b/test/sputnik/testcfg.py
index c9eb4f2..1032c13 100644
--- a/test/sputnik/testcfg.py
+++ b/test/sputnik/testcfg.py
@@ -101,7 +101,7 @@
return result
def GetBuildRequirements(self):
- return ['sample', 'sample=shell']
+ return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'sputnik.status')
diff --git a/test/test262/testcfg.py b/test/test262/testcfg.py
index aa1212e..9482046 100644
--- a/test/test262/testcfg.py
+++ b/test/test262/testcfg.py
@@ -111,7 +111,7 @@
return tests
def GetBuildRequirements(self):
- return ['sample', 'sample=shell']
+ return ['d8']
def GetTestStatus(self, sections, defs):
status_file = join(self.root, 'test262.status')
diff --git a/tools/oom_dump/README b/tools/oom_dump/README
index 0be7511..1d840b9 100644
--- a/tools/oom_dump/README
+++ b/tools/oom_dump/README
@@ -16,7 +16,9 @@
Next step is to build v8. Note: you should build x64 version of v8,
if you're on 64-bit platform, otherwise you would get a link error when
-building oom_dump.
+building oom_dump. Also, if you are testing against an older version of chrome
+you should build the corresponding version of V8 to make sure that the type-id
+enum have the correct values.
The last step is to build oom_dump itself. The following command should work:
diff --git a/tools/test.py b/tools/test.py
index ec21ffe..6132614 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -1208,7 +1208,7 @@
dest="suppress_dialogs", default=True, action="store_true")
result.add_option("--no-suppress-dialogs", help="Display Windows dialogs for crashing tests",
dest="suppress_dialogs", action="store_false")
- result.add_option("--shell", help="Path to V8 shell", default="shell")
+ result.add_option("--shell", help="Path to V8 shell", default="d8")
result.add_option("--isolates", help="Whether to test isolates", default=False, action="store_true")
result.add_option("--store-unexpected-output",
help="Store the temporary JS files from tests that fails",