diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 4d87db3be0..65b8965f1a 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -29,4 +29,5 @@ Rodolph Perfetta Ryan Dahl Subrato K De Burcu Dogan +Vlad Burlik diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index b5663744d3..caa63feba1 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,11 +1,33 @@ +2010-08-11: Version 2.3.7 + + Reduced size of heap snapshots produced by heap profiler (issue 783). + + Introduced v8::Value::IsRegExp method. + + Fixed CPU profiler crash in start / stop sequence when non-existent + name is passed (issue http://crbug.com/51594). + + Introduced new indexed property query callbacks API (issue 816). This + API is guarded by USE_NEW_QUERY_CALLBACK define and is disabled + by default. + + Removed support for object literal get/set with number/string + property name. + + Fixed handling of JSObject::elements in CalculateNetworkSize + (issue 822). + + Allow compiling with strict aliasing enabled on GCC 4.4 (issue 463). + + 2010-08-09: Version 2.3.6 - RegExp literals create a new object every time they are evaluated - (issue 704). + RegExp literals create a new object every time they are evaluated + (issue 704). - Object.seal and Object.freeze return the modified object (issue 809). + Object.seal and Object.freeze return the modified object (issue 809). - Fix building using GCC 4.4.4. + Fix building using GCC 4.4.4. 2010-08-04: Version 2.3.5 diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct index 00b8fb7219..8fc192637c 100644 --- a/deps/v8/SConstruct +++ b/deps/v8/SConstruct @@ -58,7 +58,7 @@ else: # on linux we need these compiler flags to avoid crashes in the v8 test suite # and avoid dtoa.c strict aliasing issues if os.environ.get('GCC_VERSION') == '44': - GCC_EXTRA_CCFLAGS = ['-fno-tree-vrp', '-fno-strict-aliasing'] + GCC_EXTRA_CCFLAGS = ['-fno-tree-vrp'] GCC_DTOA_EXTRA_CCFLAGS = [] else: GCC_EXTRA_CCFLAGS = [] @@ -80,7 +80,6 @@ ANDROID_FLAGS = ['-march=armv7-a', '-frerun-cse-after-loop', '-frename-registers', '-fomit-frame-pointer', - '-fno-strict-aliasing', '-finline-limit=64', '-DCAN_USE_VFP_INSTRUCTIONS=1', '-DCAN_USE_ARMV7_INSTRUCTIONS=1', diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index c99eb0d9f8..9e3cb873c6 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -194,10 +194,10 @@ class HeapGraphNode; class V8EXPORT HeapGraphEdge { public: enum Type { - CONTEXT_VARIABLE = 0, // A variable from a function context. - ELEMENT = 1, // An element of an array. - PROPERTY = 2, // A named object property. - INTERNAL = 3 // A link that can't be accessed from JS, + kContextVariable = 0, // A variable from a function context. + kElement = 1, // An element of an array. + kProperty = 2, // A named object property. + kInternal = 3 // A link that can't be accessed from JS, // thus, its name isn't a real property name. }; @@ -240,12 +240,12 @@ class V8EXPORT HeapGraphPath { class V8EXPORT HeapGraphNode { public: enum Type { - INTERNAL = 0, // Internal node, a virtual one, for housekeeping. - ARRAY = 1, // An array of elements. - STRING = 2, // A string. - OBJECT = 3, // A JS object (except for arrays and strings). - CODE = 4, // Compiled code. - CLOSURE = 5 // Function closure. + kInternal = 0, // Internal node, a virtual one, for housekeeping. + kArray = 1, // An array of elements. + kString = 2, // A string. + kObject = 3, // A JS object (except for arrays and strings). + kCode = 4, // Compiled code. + kClosure = 5 // Function closure. }; /** Returns node type (see HeapGraphNode::Type). */ @@ -268,13 +268,15 @@ class V8EXPORT HeapGraphNode { int GetSelfSize() const; /** Returns node's network (self + reachable nodes) size, in bytes. */ - int GetTotalSize() const; + int GetReachableSize() const; /** - * Returns node's private size, in bytes. That is, the size of memory - * that will be reclaimed having this node collected. + * Returns node's retained size, in bytes. That is, self + sizes of + * the objects that are reachable only from this object. In other + * words, the size of memory that will be reclaimed having this node + * collected. */ - int GetPrivateSize() const; + int GetRetainedSize() const; /** Returns child nodes count of the node. */ int GetChildrenCount() const; diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 3ac10ab917..20cef79a7f 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -919,6 +919,11 @@ class Value : public Data { */ V8EXPORT bool IsDate() const; + /** + * Returns true if this value is a RegExp. + */ + V8EXPORT bool IsRegExp() const; + V8EXPORT Local ToBoolean() const; V8EXPORT Local ToNumber() const; V8EXPORT Local ToString() const; @@ -1819,10 +1824,19 @@ typedef Handle (*IndexedPropertySetter)(uint32_t index, /** * Returns a non-empty handle if the interceptor intercepts the request. - * The result is true if the property exists and false otherwise. + * The result is true if either a boolean (true if property exists and false + * otherwise) or an integer encoding property attributes. */ +#ifdef USE_NEW_QUERY_CALLBACKS +typedef Handle (*IndexedPropertyQuery)(uint32_t index, + const AccessorInfo& info); +#else typedef Handle (*IndexedPropertyQuery)(uint32_t index, const AccessorInfo& info); +#endif + +typedef Handle (*IndexedPropertyQueryImpl)(uint32_t index, + const AccessorInfo& info); /** * Returns a non-empty handle if the deleter intercepts the request. @@ -2040,7 +2054,23 @@ class V8EXPORT FunctionTemplate : public Template { IndexedPropertyQuery query, IndexedPropertyDeleter remover, IndexedPropertyEnumerator enumerator, - Handle data); + Handle data) { + IndexedPropertyQueryImpl casted = + reinterpret_cast(query); + SetIndexedInstancePropertyHandlerImpl(getter, + setter, + casted, + remover, + enumerator, + data); + } + void SetIndexedInstancePropertyHandlerImpl( + IndexedPropertyGetter getter, + IndexedPropertySetter setter, + IndexedPropertyQueryImpl query, + IndexedPropertyDeleter remover, + IndexedPropertyEnumerator enumerator, + Handle data); void SetInstanceCallAsFunctionHandler(InvocationCallback callback, Handle data); @@ -2139,7 +2169,25 @@ class V8EXPORT ObjectTemplate : public Template { IndexedPropertyQuery query = 0, IndexedPropertyDeleter deleter = 0, IndexedPropertyEnumerator enumerator = 0, - Handle data = Handle()); + Handle data = Handle()) { + IndexedPropertyQueryImpl casted = + reinterpret_cast(query); + SetIndexedPropertyHandlerImpl(getter, + setter, + casted, + deleter, + enumerator, + data); + } + private: + void SetIndexedPropertyHandlerImpl(IndexedPropertyGetter getter, + IndexedPropertySetter setter, + IndexedPropertyQueryImpl query, + IndexedPropertyDeleter deleter, + IndexedPropertyEnumerator enumerator, + Handle data); + public: + /** * Sets the callback to be used when calling instances created from * this template as a function. If no callback is set, instances diff --git a/deps/v8/src/accessors.cc b/deps/v8/src/accessors.cc index ed0bbd7a1c..3c49846601 100644 --- a/deps/v8/src/accessors.cc +++ b/deps/v8/src/accessors.cc @@ -488,7 +488,7 @@ Object* Accessors::FunctionGetLength(Object* object, void*) { JSFunction* function = FindInPrototypeChain(object, &found_it); if (!found_it) return Smi::FromInt(0); // Check if already compiled. - if (!function->is_compiled()) { + if (!function->shared()->is_compiled()) { // If the function isn't compiled yet, the length is not computed // correctly yet. Compile it now and return the right length. HandleScope scope; diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 4fdc95f5ee..b3164dd01e 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -886,10 +886,10 @@ void FunctionTemplate::SetNamedInstancePropertyHandler( } -void FunctionTemplate::SetIndexedInstancePropertyHandler( +void FunctionTemplate::SetIndexedInstancePropertyHandlerImpl( IndexedPropertyGetter getter, IndexedPropertySetter setter, - IndexedPropertyQuery query, + IndexedPropertyQueryImpl query, IndexedPropertyDeleter remover, IndexedPropertyEnumerator enumerator, Handle data) { @@ -1054,10 +1054,10 @@ void ObjectTemplate::SetAccessCheckCallbacks( } -void ObjectTemplate::SetIndexedPropertyHandler( +void ObjectTemplate::SetIndexedPropertyHandlerImpl( IndexedPropertyGetter getter, IndexedPropertySetter setter, - IndexedPropertyQuery query, + IndexedPropertyQueryImpl query, IndexedPropertyDeleter remover, IndexedPropertyEnumerator enumerator, Handle data) { @@ -1068,12 +1068,12 @@ void ObjectTemplate::SetIndexedPropertyHandler( i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor()); i::Handle cons(constructor); - Utils::ToLocal(cons)->SetIndexedInstancePropertyHandler(getter, - setter, - query, - remover, - enumerator, - data); + Utils::ToLocal(cons)->SetIndexedInstancePropertyHandlerImpl(getter, + setter, + query, + remover, + enumerator, + data); } @@ -1792,6 +1792,13 @@ bool Value::IsDate() const { } +bool Value::IsRegExp() const { + if (IsDeadCheck("v8::Value::IsRegExp()")) return false; + i::Handle obj = Utils::OpenHandle(this); + return obj->IsJSRegExp(); +} + + Local Value::ToString() const { if (IsDeadCheck("v8::Value::ToString()")) return Local(); LOG_API("ToString"); @@ -4491,24 +4498,27 @@ const CpuProfile* CpuProfiler::StopProfiling(Handle title, } +static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) { + return const_cast( + reinterpret_cast(edge)); +} + HeapGraphEdge::Type HeapGraphEdge::GetType() const { IsDeadCheck("v8::HeapGraphEdge::GetType"); - return static_cast( - reinterpret_cast(this)->type()); + return static_cast(ToInternal(this)->type()); } Handle HeapGraphEdge::GetName() const { IsDeadCheck("v8::HeapGraphEdge::GetName"); - const i::HeapGraphEdge* edge = - reinterpret_cast(this); + i::HeapGraphEdge* edge = ToInternal(this); switch (edge->type()) { - case i::HeapGraphEdge::CONTEXT_VARIABLE: - case i::HeapGraphEdge::INTERNAL: - case i::HeapGraphEdge::PROPERTY: + case i::HeapGraphEdge::kContextVariable: + case i::HeapGraphEdge::kInternal: + case i::HeapGraphEdge::kProperty: return Handle(ToApi(i::Factory::LookupAsciiSymbol( edge->name()))); - case i::HeapGraphEdge::ELEMENT: + case i::HeapGraphEdge::kElement: return Handle(ToApi(i::Factory::NewNumberFromInt( edge->index()))); default: UNREACHABLE(); @@ -4519,28 +4529,32 @@ Handle HeapGraphEdge::GetName() const { const HeapGraphNode* HeapGraphEdge::GetFromNode() const { IsDeadCheck("v8::HeapGraphEdge::GetFromNode"); - const i::HeapEntry* from = - reinterpret_cast(this)->from(); + const i::HeapEntry* from = ToInternal(this)->From(); return reinterpret_cast(from); } const HeapGraphNode* HeapGraphEdge::GetToNode() const { IsDeadCheck("v8::HeapGraphEdge::GetToNode"); - const i::HeapEntry* to = - reinterpret_cast(this)->to(); + const i::HeapEntry* to = ToInternal(this)->to(); return reinterpret_cast(to); } +static i::HeapGraphPath* ToInternal(const HeapGraphPath* path) { + return const_cast( + reinterpret_cast(path)); +} + + int HeapGraphPath::GetEdgesCount() const { - return reinterpret_cast(this)->path()->length(); + return ToInternal(this)->path()->length(); } const HeapGraphEdge* HeapGraphPath::GetEdge(int index) const { return reinterpret_cast( - reinterpret_cast(this)->path()->at(index)); + ToInternal(this)->path()->at(index)); } @@ -4555,137 +4569,136 @@ const HeapGraphNode* HeapGraphPath::GetToNode() const { } +static i::HeapEntry* ToInternal(const HeapGraphNode* entry) { + return const_cast( + reinterpret_cast(entry)); +} + + HeapGraphNode::Type HeapGraphNode::GetType() const { IsDeadCheck("v8::HeapGraphNode::GetType"); - return static_cast( - reinterpret_cast(this)->type()); + return static_cast(ToInternal(this)->type()); } Handle HeapGraphNode::GetName() const { IsDeadCheck("v8::HeapGraphNode::GetName"); return Handle(ToApi(i::Factory::LookupAsciiSymbol( - reinterpret_cast(this)->name()))); + ToInternal(this)->name()))); } uint64_t HeapGraphNode::GetId() const { IsDeadCheck("v8::HeapGraphNode::GetId"); - return reinterpret_cast(this)->id(); + return ToInternal(this)->id(); } int HeapGraphNode::GetSelfSize() const { IsDeadCheck("v8::HeapGraphNode::GetSelfSize"); - return reinterpret_cast(this)->self_size(); + return ToInternal(this)->self_size(); } -int HeapGraphNode::GetTotalSize() const { - IsDeadCheck("v8::HeapSnapshot::GetHead"); - return const_cast( - reinterpret_cast(this))->TotalSize(); +int HeapGraphNode::GetReachableSize() const { + IsDeadCheck("v8::HeapSnapshot::GetReachableSize"); + return ToInternal(this)->ReachableSize(); } -int HeapGraphNode::GetPrivateSize() const { - IsDeadCheck("v8::HeapSnapshot::GetPrivateSize"); - return const_cast( - reinterpret_cast(this))->NonSharedTotalSize(); +int HeapGraphNode::GetRetainedSize() const { + IsDeadCheck("v8::HeapSnapshot::GetRetainedSize"); + return ToInternal(this)->RetainedSize(); } int HeapGraphNode::GetChildrenCount() const { IsDeadCheck("v8::HeapSnapshot::GetChildrenCount"); - return reinterpret_cast(this)->children()->length(); + return ToInternal(this)->children().length(); } const HeapGraphEdge* HeapGraphNode::GetChild(int index) const { IsDeadCheck("v8::HeapSnapshot::GetChild"); return reinterpret_cast( - reinterpret_cast(this)->children()->at(index)); + &ToInternal(this)->children()[index]); } int HeapGraphNode::GetRetainersCount() const { IsDeadCheck("v8::HeapSnapshot::GetRetainersCount"); - return reinterpret_cast(this)->retainers()->length(); + return ToInternal(this)->retainers().length(); } const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const { IsDeadCheck("v8::HeapSnapshot::GetRetainer"); return reinterpret_cast( - reinterpret_cast(this)->retainers()->at(index)); + ToInternal(this)->retainers()[index]); } int HeapGraphNode::GetRetainingPathsCount() const { IsDeadCheck("v8::HeapSnapshot::GetRetainingPathsCount"); - return const_cast( - reinterpret_cast( - this))->GetRetainingPaths()->length(); + return ToInternal(this)->GetRetainingPaths()->length(); } const HeapGraphPath* HeapGraphNode::GetRetainingPath(int index) const { IsDeadCheck("v8::HeapSnapshot::GetRetainingPath"); return reinterpret_cast( - const_cast( - reinterpret_cast( - this))->GetRetainingPaths()->at(index)); + ToInternal(this)->GetRetainingPaths()->at(index)); } const HeapGraphNode* HeapSnapshotsDiff::GetAdditionsRoot() const { IsDeadCheck("v8::HeapSnapshotsDiff::GetAdditionsRoot"); - const i::HeapSnapshotsDiff* diff = - reinterpret_cast(this); + i::HeapSnapshotsDiff* diff = + const_cast( + reinterpret_cast(this)); return reinterpret_cast(diff->additions_root()); } const HeapGraphNode* HeapSnapshotsDiff::GetDeletionsRoot() const { IsDeadCheck("v8::HeapSnapshotsDiff::GetDeletionsRoot"); - const i::HeapSnapshotsDiff* diff = - reinterpret_cast(this); + i::HeapSnapshotsDiff* diff = + const_cast( + reinterpret_cast(this)); return reinterpret_cast(diff->deletions_root()); } +static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) { + return const_cast( + reinterpret_cast(snapshot)); +} + + unsigned HeapSnapshot::GetUid() const { IsDeadCheck("v8::HeapSnapshot::GetUid"); - return reinterpret_cast(this)->uid(); + return ToInternal(this)->uid(); } Handle HeapSnapshot::GetTitle() const { IsDeadCheck("v8::HeapSnapshot::GetTitle"); - const i::HeapSnapshot* snapshot = - reinterpret_cast(this); return Handle(ToApi(i::Factory::LookupAsciiSymbol( - snapshot->title()))); + ToInternal(this)->title()))); } const HeapGraphNode* HeapSnapshot::GetRoot() const { IsDeadCheck("v8::HeapSnapshot::GetHead"); - const i::HeapSnapshot* snapshot = - reinterpret_cast(this); - return reinterpret_cast(snapshot->const_root()); + return reinterpret_cast(ToInternal(this)->root()); } const HeapSnapshotsDiff* HeapSnapshot::CompareWith( const HeapSnapshot* snapshot) const { IsDeadCheck("v8::HeapSnapshot::CompareWith"); - i::HeapSnapshot* snapshot1 = const_cast( - reinterpret_cast(this)); - i::HeapSnapshot* snapshot2 = const_cast( - reinterpret_cast(snapshot)); return reinterpret_cast( - snapshot1->CompareWith(snapshot2)); + ToInternal(this)->CompareWith(ToInternal(snapshot))); } diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc index b1f29ba381..37768e8d5f 100644 --- a/deps/v8/src/arm/builtins-arm.cc +++ b/deps/v8/src/arm/builtins-arm.cc @@ -1050,7 +1050,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ ldr(r2, FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset)); __ mov(r2, Operand(r2, ASR, kSmiTagSize)); - __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset)); + __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeOffset)); __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag)); __ cmp(r2, r0); // Check formal and actual parameter counts. __ Jump(Handle(builtin(ArgumentsAdaptorTrampoline)), diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc index 4bcf1a07df..aec80d7315 100644 --- a/deps/v8/src/arm/codegen-arm.cc +++ b/deps/v8/src/arm/codegen-arm.cc @@ -1532,9 +1532,8 @@ void CodeGenerator::CallApplyLazy(Expression* applicand, __ BranchOnSmi(r0, &build_args); __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE); __ b(ne, &build_args); - __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); Handle apply_code(Builtins::builtin(Builtins::FunctionApply)); - __ ldr(r1, FieldMemOperand(r0, SharedFunctionInfo::kCodeOffset)); + __ ldr(r1, FieldMemOperand(r0, JSFunction::kCodeOffset)); __ cmp(r1, Operand(apply_code)); __ b(ne, &build_args); @@ -4176,21 +4175,21 @@ void CodeGenerator::VisitCallNew(CallNew* node) { void CodeGenerator::GenerateClassOf(ZoneList* args) { - VirtualFrame::SpilledScope spilled_scope(frame_); - ASSERT(args->length() == 1); JumpTarget leave, null, function, non_function_constructor; + Register scratch = VirtualFrame::scratch0(); - // Load the object into r0. + // Load the object into register. + ASSERT(args->length() == 1); Load(args->at(0)); - frame_->EmitPop(r0); + Register tos = frame_->PopToRegister(); // If the object is a smi, we return null. - __ tst(r0, Operand(kSmiTagMask)); + __ tst(tos, Operand(kSmiTagMask)); null.Branch(eq); // Check that the object is a JS object but take special care of JS // functions to make sure they have 'Function' as their class. - __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); + __ CompareObjectType(tos, tos, scratch, FIRST_JS_OBJECT_TYPE); null.Branch(lt); // As long as JS_FUNCTION_TYPE is the last instance type and it is @@ -4198,37 +4197,38 @@ void CodeGenerator::GenerateClassOf(ZoneList* args) { // LAST_JS_OBJECT_TYPE. STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); STATIC_ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); - __ cmp(r1, Operand(JS_FUNCTION_TYPE)); + __ cmp(scratch, Operand(JS_FUNCTION_TYPE)); function.Branch(eq); // Check if the constructor in the map is a function. - __ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset)); - __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); + __ ldr(tos, FieldMemOperand(tos, Map::kConstructorOffset)); + __ CompareObjectType(tos, scratch, scratch, JS_FUNCTION_TYPE); non_function_constructor.Branch(ne); - // The r0 register now contains the constructor function. Grab the + // The tos register now contains the constructor function. Grab the // instance class name from there. - __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); - __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset)); - frame_->EmitPush(r0); + __ ldr(tos, FieldMemOperand(tos, JSFunction::kSharedFunctionInfoOffset)); + __ ldr(tos, + FieldMemOperand(tos, SharedFunctionInfo::kInstanceClassNameOffset)); + frame_->EmitPush(tos); leave.Jump(); // Functions have class 'Function'. function.Bind(); - __ mov(r0, Operand(Factory::function_class_symbol())); - frame_->EmitPush(r0); + __ mov(tos, Operand(Factory::function_class_symbol())); + frame_->EmitPush(tos); leave.Jump(); // Objects with a non-function constructor have class 'Object'. non_function_constructor.Bind(); - __ mov(r0, Operand(Factory::Object_symbol())); - frame_->EmitPush(r0); + __ mov(tos, Operand(Factory::Object_symbol())); + frame_->EmitPush(tos); leave.Jump(); // Non-JS objects have class null. null.Bind(); - __ LoadRoot(r0, Heap::kNullValueRootIndex); - frame_->EmitPush(r0); + __ LoadRoot(tos, Heap::kNullValueRootIndex); + frame_->EmitPush(tos); // All done. leave.Bind(); @@ -4236,45 +4236,51 @@ void CodeGenerator::GenerateClassOf(ZoneList* args) { void CodeGenerator::GenerateValueOf(ZoneList* args) { - VirtualFrame::SpilledScope spilled_scope(frame_); - ASSERT(args->length() == 1); + Register scratch = VirtualFrame::scratch0(); JumpTarget leave; + + ASSERT(args->length() == 1); Load(args->at(0)); - frame_->EmitPop(r0); // r0 contains object. + Register tos = frame_->PopToRegister(); // tos contains object. // if (object->IsSmi()) return the object. - __ tst(r0, Operand(kSmiTagMask)); + __ tst(tos, Operand(kSmiTagMask)); leave.Branch(eq); // It is a heap object - get map. If (!object->IsJSValue()) return the object. - __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); + __ CompareObjectType(tos, scratch, scratch, JS_VALUE_TYPE); leave.Branch(ne); // Load the value. - __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); + __ ldr(tos, FieldMemOperand(tos, JSValue::kValueOffset)); leave.Bind(); - frame_->EmitPush(r0); + frame_->EmitPush(tos); } void CodeGenerator::GenerateSetValueOf(ZoneList* args) { - VirtualFrame::SpilledScope spilled_scope(frame_); - ASSERT(args->length() == 2); + Register scratch1 = VirtualFrame::scratch0(); + Register scratch2 = VirtualFrame::scratch1(); JumpTarget leave; + + ASSERT(args->length() == 2); Load(args->at(0)); // Load the object. Load(args->at(1)); // Load the value. - frame_->EmitPop(r0); // r0 contains value - frame_->EmitPop(r1); // r1 contains object + Register value = frame_->PopToRegister(); + Register object = frame_->PopToRegister(value); // if (object->IsSmi()) return object. - __ tst(r1, Operand(kSmiTagMask)); + __ tst(object, Operand(kSmiTagMask)); leave.Branch(eq); // It is a heap object - get map. If (!object->IsJSValue()) return the object. - __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); + __ CompareObjectType(object, scratch1, scratch1, JS_VALUE_TYPE); leave.Branch(ne); // Store the value. - __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); + __ str(value, FieldMemOperand(object, JSValue::kValueOffset)); // Update the write barrier. - __ RecordWrite(r1, Operand(JSValue::kValueOffset - kHeapObjectTag), r2, r3); + __ RecordWrite(object, + Operand(JSValue::kValueOffset - kHeapObjectTag), + scratch1, + scratch2); // Leave. leave.Bind(); - frame_->EmitPush(r0); + frame_->EmitPush(value); } @@ -4558,22 +4564,18 @@ class DeferredStringCharCodeAt : public DeferredCode { // This generates code that performs a String.prototype.charCodeAt() call // or returns a smi in order to trigger conversion. void CodeGenerator::GenerateStringCharCodeAt(ZoneList* args) { - VirtualFrame::SpilledScope spilled_scope(frame_); Comment(masm_, "[ GenerateStringCharCodeAt"); ASSERT(args->length() == 2); Load(args->at(0)); Load(args->at(1)); - Register index = r1; - Register object = r2; - - frame_->EmitPop(r1); - frame_->EmitPop(r2); + Register index = frame_->PopToRegister(); + Register object = frame_->PopToRegister(index); // We need two extra registers. - Register scratch = r3; - Register result = r0; + Register scratch = VirtualFrame::scratch0(); + Register result = VirtualFrame::scratch1(); DeferredStringCharCodeAt* deferred = new DeferredStringCharCodeAt(object, @@ -4608,16 +4610,13 @@ class DeferredStringCharFromCode : public DeferredCode { // Generates code for creating a one-char string from a char code. void CodeGenerator::GenerateStringCharFromCode(ZoneList* args) { - VirtualFrame::SpilledScope spilled_scope(frame_); Comment(masm_, "[ GenerateStringCharFromCode"); ASSERT(args->length() == 1); Load(args->at(0)); - Register code = r1; - Register result = r0; - - frame_->EmitPop(code); + Register result = frame_->GetTOSRegister(); + Register code = frame_->PopToRegister(result); DeferredStringCharFromCode* deferred = new DeferredStringCharFromCode( code, result); @@ -4679,23 +4678,20 @@ class DeferredStringCharAt : public DeferredCode { // This generates code that performs a String.prototype.charAt() call // or returns a smi in order to trigger conversion. void CodeGenerator::GenerateStringCharAt(ZoneList* args) { - VirtualFrame::SpilledScope spilled_scope(frame_); Comment(masm_, "[ GenerateStringCharAt"); ASSERT(args->length() == 2); Load(args->at(0)); Load(args->at(1)); - Register index = r1; - Register object = r2; - - frame_->EmitPop(r1); - frame_->EmitPop(r2); + Register index = frame_->PopToRegister(); + Register object = frame_->PopToRegister(index); // We need three extra registers. - Register scratch1 = r3; - Register scratch2 = r4; - Register result = r0; + Register scratch1 = VirtualFrame::scratch0(); + Register scratch2 = VirtualFrame::scratch1(); + // Use r6 without notifying the virtual frame. + Register result = r6; DeferredStringCharAt* deferred = new DeferredStringCharAt(object, @@ -4874,13 +4870,13 @@ void CodeGenerator::GenerateArgumentsLength(ZoneList* args) { void CodeGenerator::GenerateArguments(ZoneList* args) { - VirtualFrame::SpilledScope spilled_scope(frame_); ASSERT(args->length() == 1); // Satisfy contract with ArgumentsAccessStub: // Load the key into r1 and the formal parameters count into r0. Load(args->at(0)); - frame_->EmitPop(r1); + frame_->PopToR1(); + frame_->SpillAll(); __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); // Call the shared stub to get to arguments[key]. @@ -5108,9 +5104,7 @@ class DeferredSearchCache: public DeferredCode { void DeferredSearchCache::Generate() { __ Push(cache_, key_); __ CallRuntime(Runtime::kGetFromCache, 2); - if (!dst_.is(r0)) { - __ mov(dst_, r0); - } + __ Move(dst_, r0); } @@ -5130,33 +5124,42 @@ void CodeGenerator::GenerateGetFromCache(ZoneList* args) { Load(args->at(1)); - VirtualFrame::SpilledScope spilled_scope(frame_); - - frame_->EmitPop(r2); + frame_->PopToR1(); + frame_->SpillAll(); + Register key = r1; // Just poped to r1 + Register result = r0; // Free, as frame has just been spilled. + Register scratch1 = VirtualFrame::scratch0(); + Register scratch2 = VirtualFrame::scratch1(); - __ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX)); - __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); - __ ldr(r1, ContextOperand(r1, Context::JSFUNCTION_RESULT_CACHES_INDEX)); - __ ldr(r1, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(cache_id))); + __ ldr(scratch1, ContextOperand(cp, Context::GLOBAL_INDEX)); + __ ldr(scratch1, + FieldMemOperand(scratch1, GlobalObject::kGlobalContextOffset)); + __ ldr(scratch1, + ContextOperand(scratch1, Context::JSFUNCTION_RESULT_CACHES_INDEX)); + __ ldr(scratch1, + FieldMemOperand(scratch1, FixedArray::OffsetOfElementAt(cache_id))); - DeferredSearchCache* deferred = new DeferredSearchCache(r0, r1, r2); + DeferredSearchCache* deferred = + new DeferredSearchCache(result, scratch1, key); const int kFingerOffset = FixedArray::OffsetOfElementAt(JSFunctionResultCache::kFingerIndex); STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); - __ ldr(r0, FieldMemOperand(r1, kFingerOffset)); - // r0 now holds finger offset as a smi. - __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - // r3 now points to the start of fixed array elements. - __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex)); - // Note side effect of PreIndex: r3 now points to the key of the pair. - __ cmp(r2, r0); + __ ldr(result, FieldMemOperand(scratch1, kFingerOffset)); + // result now holds finger offset as a smi. + __ add(scratch2, scratch1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); + // scratch2 now points to the start of fixed array elements. + __ ldr(result, + MemOperand( + scratch2, result, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex)); + // Note side effect of PreIndex: scratch2 now points to the key of the pair. + __ cmp(key, result); deferred->Branch(ne); - __ ldr(r0, MemOperand(r3, kPointerSize)); + __ ldr(result, MemOperand(scratch2, kPointerSize)); deferred->BindExit(); - frame_->EmitPush(r0); + frame_->EmitPush(result); } @@ -6851,6 +6854,11 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) { __ str(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); __ str(r1, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); + // Initialize the code pointer in the function to be the one + // found in the shared function info object. + __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset)); + __ str(r3, FieldMemOperand(r0, JSFunction::kCodeOffset)); + // Return result. The argument function info has been popped already. __ Ret(); @@ -10444,11 +10452,9 @@ void StringCharCodeAtGenerator::GenerateSlow( // NumberToSmi discards numbers that are not exact integers. __ CallRuntime(Runtime::kNumberToSmi, 1); } - if (!scratch_.is(r0)) { - // Save the conversion result before the pop instructions below - // have a chance to overwrite it. - __ mov(scratch_, r0); - } + // Save the conversion result before the pop instructions below + // have a chance to overwrite it. + __ Move(scratch_, r0); __ pop(index_); __ pop(object_); // Reload the instance type. @@ -10467,9 +10473,7 @@ void StringCharCodeAtGenerator::GenerateSlow( call_helper.BeforeCall(masm); __ Push(object_, index_); __ CallRuntime(Runtime::kStringCharCodeAt, 2); - if (!result_.is(r0)) { - __ mov(result_, r0); - } + __ Move(result_, r0); call_helper.AfterCall(masm); __ jmp(&exit_); @@ -10510,9 +10514,7 @@ void StringCharFromCodeGenerator::GenerateSlow( call_helper.BeforeCall(masm); __ push(code_); __ CallRuntime(Runtime::kCharFromCode, 1); - if (!result_.is(r0)) { - __ mov(result_, r0); - } + __ Move(result_, r0); call_helper.AfterCall(masm); __ jmp(&exit_); diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index 9c25ccde2f..7a03641a2f 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -757,7 +757,7 @@ void MacroAssembler::InvokeFunction(Register fun, SharedFunctionInfo::kFormalParameterCountOffset)); mov(expected_reg, Operand(expected_reg, ASR, kSmiTagSize)); ldr(code_reg, - MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); + MemOperand(r1, JSFunction::kCodeOffset - kHeapObjectTag)); add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); ParameterCount expected(expected_reg); @@ -1508,8 +1508,7 @@ void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { // Make sure the code objects in the builtins object and in the // builtin function are the same. push(r1); - ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); - ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kCodeOffset)); + ldr(r1, FieldMemOperand(r1, JSFunction::kCodeOffset)); cmp(r1, target); Assert(eq, "Builtin code object changed"); pop(r1); diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index e1d4489d44..0d59505c09 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -56,7 +56,7 @@ class SourceCodeCache BASE_EMBEDDED { } void Iterate(ObjectVisitor* v) { - v->VisitPointer(BitCast(&cache_)); + v->VisitPointer(BitCast(&cache_)); } @@ -470,6 +470,7 @@ Handle Genesis::CreateEmptyFunction() { Handle code = Handle(Builtins::builtin(Builtins::EmptyFunction)); empty_function->set_code(*code); + empty_function->shared()->set_code(*code); Handle source = Factory::NewStringFromAscii(CStrVector("() {}")); Handle