diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore new file mode 100644 index 0000000000..685e9a2f9d --- /dev/null +++ b/deps/v8/.gitignore @@ -0,0 +1,21 @@ +*.a +*.exe +*.lib +*.log +*.map +*.mk +*.ncb +*.pyc +*.scons* +*.suo +*.user +*.xcodeproj +d8 +d8_g +shell +shell_g +/obj/ +/tools/visual_studio/Debug +/tools/visual_studio/Release +/xcodebuild/ +TAGS diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 03b96f1579..e786802450 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,21 @@ +2009-08-12: Version 1.3.3 + + Fix issue 417: incorrect %t placeholder expansion. + + Add .gitignore file similar to Chromium's one. + + Fix SConstruct file to build with new logging code for Android. + + API: added function to find instance of template in prototype + chain. Inlined Object::IsInstanceOf. + + Land change to notify valgrind when we modify code on x86. + + Add api call to determine whether a string can be externalized. + + Add a write() command to d8. + + 2009-08-05: Version 1.3.2 Started new compiler infrastructure for two-pass compilation using a diff --git a/deps/v8/LICENSE b/deps/v8/LICENSE index 7301556f77..553cf4755f 100644 --- a/deps/v8/LICENSE +++ b/deps/v8/LICENSE @@ -20,6 +20,12 @@ are: copyrighted by Douglas Crockford and Baruch Even and released under an MIT license. + - Valgrind client API header, located at third_party/valgrind/valgrind.h + This is release under the BSD license. + + - Valgrind client API header, located at third_party/valgrind/valgrind.h + This is release under the BSD license. + These libraries have their own licenses; we recommend you read them, as their terms may differ from the terms below. diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct index 8b48ad4590..c981ef9139 100644 --- a/deps/v8/SConstruct +++ b/deps/v8/SConstruct @@ -79,7 +79,9 @@ ANDROID_INCLUDES = [ANDROID_TOP + '/bionic/libc/arch-arm/include', ANDROID_TOP + '/bionic/libc/kernel/arch-arm', ANDROID_TOP + '/bionic/libm/include', ANDROID_TOP + '/bionic/libm/include/arch/arm', - ANDROID_TOP + '/bionic/libthread_db/include'] + ANDROID_TOP + '/bionic/libthread_db/include', + ANDROID_TOP + '/frameworks/base/include', + ANDROID_TOP + '/system/core/include'] ANDROID_LINKFLAGS = ['-nostdlib', '-Bdynamic', @@ -331,7 +333,7 @@ CCTEST_EXTRA_FLAGS = { 'CPPPATH': ANDROID_INCLUDES, 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'], 'LINKFLAGS': ANDROID_LINKFLAGS, - 'LIBS': ['c', 'stdc++', 'm'], + 'LIBS': ['log', 'c', 'stdc++', 'm'], 'mode:release': { 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG'] } @@ -382,7 +384,7 @@ SAMPLE_FLAGS = { 'CPPPATH': ANDROID_INCLUDES, 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'], 'LINKFLAGS': ANDROID_LINKFLAGS, - 'LIBS': ['c', 'stdc++', 'm'], + 'LIBS': ['log', 'c', 'stdc++', 'm'], 'mode:release': { 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG'] } @@ -470,7 +472,7 @@ D8_FLAGS = { 'os:android': { 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'], 'LINKFLAGS': ANDROID_LINKFLAGS, - 'LIBS': ['c', 'stdc++', 'm'], + 'LIBS': ['log', 'c', 'stdc++', 'm'], }, 'os:win32': { 'LIBS': ['winmm', 'ws2_32'], diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 87e71031c7..23c4425f86 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -901,6 +901,11 @@ class V8EXPORT String : public Primitive { */ bool MakeExternal(ExternalAsciiStringResource* resource); + /** + * Returns true if this string can be made external. + */ + bool CanMakeExternal(); + /** Creates an undetectable string from the supplied ascii or utf-8 data.*/ static Local NewUndetectable(const char* data, int length = -1); @@ -1098,6 +1103,12 @@ class V8EXPORT Object : public Value { */ Local GetPrototype(); + /** + * Finds an instance of the given function template in the prototype + * chain. + */ + Local FindInstanceInPrototypeChain(Handle tmpl); + /** * Call builtin Object.prototype.toString on this object. * This is different from Value::ToString() that may call diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 9bc623a63a..d02a2e4484 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -1928,6 +1928,22 @@ Local v8::Object::GetPrototype() { } +Local v8::Object::FindInstanceInPrototypeChain( + v8::Handle tmpl) { + ON_BAILOUT("v8::Object::FindInstanceInPrototypeChain()", + return Local()); + ENTER_V8; + i::JSObject* object = *Utils::OpenHandle(this); + i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl); + while (!object->IsInstanceOf(tmpl_info)) { + i::Object* prototype = object->GetPrototype(); + if (!prototype->IsJSObject()) return Local(); + object = i::JSObject::cast(prototype); + } + return Utils::ToLocal(i::Handle(object)); +} + + Local v8::Object::GetPropertyNames() { ON_BAILOUT("v8::Object::GetPropertyNames()", return Local()); ENTER_V8; @@ -2573,9 +2589,12 @@ Persistent v8::Context::New( i::Handle env; { ENTER_V8; +#if defined(ANDROID) + // On mobile devices, full GC is expensive. +#else // Give the heap a chance to cleanup if we've disposed contexts. i::Heap::CollectAllGarbageIfContextDisposed(); - +#endif v8::Handle proxy_template = global_template; i::Handle proxy_constructor; i::Handle global_constructor; @@ -2967,7 +2986,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { if (IsDeadCheck("v8::String::MakeExternal()")) return false; if (this->IsExternal()) return false; // Already an external string. ENTER_V8; - i::Handle obj = Utils::OpenHandle(this); + i::Handle obj = Utils::OpenHandle(this); bool result = obj->MakeExternal(resource); if (result && !obj->IsSymbol()) { // Operation was successful and the string is not a symbol. In this case @@ -3003,7 +3022,7 @@ bool v8::String::MakeExternal( if (IsDeadCheck("v8::String::MakeExternal()")) return false; if (this->IsExternal()) return false; // Already an external string. ENTER_V8; - i::Handle obj = Utils::OpenHandle(this); + i::Handle obj = Utils::OpenHandle(this); bool result = obj->MakeExternal(resource); if (result && !obj->IsSymbol()) { // Operation was successful and the string is not a symbol. In this case @@ -3018,6 +3037,17 @@ bool v8::String::MakeExternal( } +bool v8::String::CanMakeExternal() { + if (IsDeadCheck("v8::String::CanMakeExternal()")) return false; + i::Handle obj = Utils::OpenHandle(this); + int size = obj->Size(); // Byte size of the original string. + if (size < i::ExternalString::kSize) + return false; + i::StringShape shape(*obj); + return !shape.IsExternal(); +} + + Local v8::Object::New() { EnsureInitialized("v8::Object::New()"); LOG_API("Object::New"); diff --git a/deps/v8/src/arm/cfg-arm.cc b/deps/v8/src/arm/cfg-arm.cc index 109067bea2..34e64b30dc 100644 --- a/deps/v8/src/arm/cfg-arm.cc +++ b/deps/v8/src/arm/cfg-arm.cc @@ -29,6 +29,7 @@ #include "cfg.h" #include "codegen-inl.h" +#include "codegen-arm.h" // Include after codegen-inl.h. #include "macro-assembler-arm.h" namespace v8 { @@ -42,6 +43,14 @@ void InstructionBlock::Compile(MacroAssembler* masm) { { Comment cmt(masm, "[ InstructionBlock"); for (int i = 0, len = instructions_.length(); i < len; i++) { + // If the location of the current instruction is a temp, then the + // instruction cannot be in tail position in the block. Allocate the + // temp based on peeking ahead to the next instruction. + Instruction* instr = instructions_[i]; + Location* loc = instr->location(); + if (loc->is_temporary()) { + instructions_[i+1]->FastAllocate(TempLocation::cast(loc)); + } instructions_[i]->Compile(masm); } } @@ -91,31 +100,199 @@ void ExitNode::Compile(MacroAssembler* masm) { } +void PropLoadInstr::Compile(MacroAssembler* masm) { + // The key should not be on the stack---if it is a compiler-generated + // temporary it is in the accumulator. + ASSERT(!key()->is_on_stack()); + + Comment cmnt(masm, "[ Load from Property"); + // If the key is known at compile-time we may be able to use a load IC. + bool is_keyed_load = true; + if (key()->is_constant()) { + // Still use the keyed load IC if the key can be parsed as an integer so + // we will get into the case that handles [] on string objects. + Handle key_val = Constant::cast(key())->handle(); + uint32_t ignored; + if (key_val->IsSymbol() && + !String::cast(*key_val)->AsArrayIndex(&ignored)) { + is_keyed_load = false; + } + } + + if (!object()->is_on_stack()) object()->Push(masm); + + if (is_keyed_load) { + key()->Push(masm); + Handle ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); + __ Call(ic, RelocInfo::CODE_TARGET); + // Discard key and receiver. + __ add(sp, sp, Operand(2 * kPointerSize)); + } else { + key()->Get(masm, r2); + Handle ic(Builtins::builtin(Builtins::LoadIC_Initialize)); + __ Call(ic, RelocInfo::CODE_TARGET); + __ pop(); // Discard receiver. + } + location()->Set(masm, r0); +} + + +void BinaryOpInstr::Compile(MacroAssembler* masm) { + // The right-hand value should not be on the stack---if it is a + // compiler-generated temporary it is in the accumulator. + ASSERT(!right()->is_on_stack()); + + Comment cmnt(masm, "[ BinaryOpInstr"); + // We can overwrite one of the operands if it is a temporary. + OverwriteMode mode = NO_OVERWRITE; + if (left()->is_temporary()) { + mode = OVERWRITE_LEFT; + } else if (right()->is_temporary()) { + mode = OVERWRITE_RIGHT; + } + + // Move left to r1 and right to r0. + left()->Get(masm, r1); + right()->Get(masm, r0); + GenericBinaryOpStub stub(op(), mode); + __ CallStub(&stub); + location()->Set(masm, r0); +} + + void ReturnInstr::Compile(MacroAssembler* masm) { + // The location should be 'Effect'. As a side effect, move the value to + // the accumulator. Comment cmnt(masm, "[ ReturnInstr"); - value_->ToRegister(masm, r0); + value()->Get(masm, r0); } -void Constant::ToRegister(MacroAssembler* masm, Register reg) { +void Constant::Get(MacroAssembler* masm, Register reg) { __ mov(reg, Operand(handle_)); } -void SlotLocation::ToRegister(MacroAssembler* masm, Register reg) { - switch (type_) { +void Constant::Push(MacroAssembler* masm) { + __ mov(ip, Operand(handle_)); + __ push(ip); +} + + +static MemOperand ToMemOperand(SlotLocation* loc) { + switch (loc->type()) { case Slot::PARAMETER: { int count = CfgGlobals::current()->fun()->scope()->num_parameters(); - __ ldr(reg, MemOperand(fp, (1 + count - index_) * kPointerSize)); - break; + return MemOperand(fp, (1 + count - loc->index()) * kPointerSize); } case Slot::LOCAL: { const int kOffset = JavaScriptFrameConstants::kLocal0Offset; - __ ldr(reg, MemOperand(fp, kOffset - index_ * kPointerSize)); - break; + return MemOperand(fp, kOffset - loc->index() * kPointerSize); } default: UNREACHABLE(); + return MemOperand(r0); + } +} + + +void Constant::MoveToSlot(MacroAssembler* masm, SlotLocation* loc) { + __ mov(ip, Operand(handle_)); + __ str(ip, ToMemOperand(loc)); +} + + +void SlotLocation::Get(MacroAssembler* masm, Register reg) { + __ ldr(reg, ToMemOperand(this)); +} + + +void SlotLocation::Set(MacroAssembler* masm, Register reg) { + __ str(reg, ToMemOperand(this)); +} + + +void SlotLocation::Push(MacroAssembler* masm) { + __ ldr(ip, ToMemOperand(this)); + __ push(ip); // Push will not destroy ip. +} + + +void SlotLocation::Move(MacroAssembler* masm, Value* value) { + // Double dispatch. + value->MoveToSlot(masm, this); +} + + +void SlotLocation::MoveToSlot(MacroAssembler* masm, SlotLocation* loc) { + __ ldr(ip, ToMemOperand(this)); + __ str(ip, ToMemOperand(loc)); +} + + +void TempLocation::Get(MacroAssembler* masm, Register reg) { + switch (where_) { + case ACCUMULATOR: + if (!reg.is(r0)) __ mov(reg, r0); + break; + case STACK: + __ pop(reg); + break; + case NOT_ALLOCATED: + UNREACHABLE(); + } +} + + +void TempLocation::Set(MacroAssembler* masm, Register reg) { + switch (where_) { + case ACCUMULATOR: + if (!reg.is(r0)) __ mov(r0, reg); + break; + case STACK: + __ push(reg); + break; + case NOT_ALLOCATED: + UNREACHABLE(); + } +} + + +void TempLocation::Push(MacroAssembler* masm) { + switch (where_) { + case ACCUMULATOR: + __ push(r0); + break; + case STACK: + case NOT_ALLOCATED: + UNREACHABLE(); + } +} + + +void TempLocation::Move(MacroAssembler* masm, Value* value) { + switch (where_) { + case ACCUMULATOR: + value->Get(masm, r0); + case STACK: + value->Push(masm); + break; + case NOT_ALLOCATED: + UNREACHABLE(); + } +} + + +void TempLocation::MoveToSlot(MacroAssembler* masm, SlotLocation* loc) { + switch (where_) { + case ACCUMULATOR: + __ str(r0, ToMemOperand(loc)); + case STACK: + __ pop(ip); + __ str(ip, ToMemOperand(loc)); + break; + case NOT_ALLOCATED: + UNREACHABLE(); } } diff --git a/deps/v8/src/arm/codegen-arm-inl.h b/deps/v8/src/arm/codegen-arm-inl.h index 5a29a45002..9ff02cb4a9 100644 --- a/deps/v8/src/arm/codegen-arm-inl.h +++ b/deps/v8/src/arm/codegen-arm-inl.h @@ -34,6 +34,37 @@ namespace internal { #define __ ACCESS_MASM(masm_) +void CodeGenerator::LoadConditionAndSpill(Expression* expression, + TypeofState typeof_state, + JumpTarget* true_target, + JumpTarget* false_target, + bool force_control) { + LoadCondition(expression, typeof_state, true_target, false_target, + force_control); +} + + +void CodeGenerator::LoadAndSpill(Expression* expression, + TypeofState typeof_state) { + Load(expression, typeof_state); +} + + +void CodeGenerator::VisitAndSpill(Statement* statement) { + Visit(statement); +} + + +void CodeGenerator::VisitStatementsAndSpill(ZoneList* statements) { + VisitStatements(statements); +} + + +void Reference::GetValueAndSpill(TypeofState typeof_state) { + GetValue(typeof_state); +} + + // Platform-specific inline functions. void DeferredCode::Jump() { __ jmp(&entry_label_); } diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc index 5f8149e2ea..d3507ec0e3 100644 --- a/deps/v8/src/arm/codegen-arm.cc +++ b/deps/v8/src/arm/codegen-arm.cc @@ -133,8 +133,7 @@ CodeGenerator::CodeGenerator(int buffer_size, Handle