Browse Source

Upgrade V8 to 2.3.4

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
a6bc68a83b
  1. 25
      deps/v8/ChangeLog
  2. 1
      deps/v8/src/arm/codegen-arm.cc
  3. 5
      deps/v8/src/arm/debug-arm.cc
  4. 2
      deps/v8/src/arm/full-codegen-arm.cc
  5. 5
      deps/v8/src/arm/virtual-frame-arm.cc
  6. 2
      deps/v8/src/codegen.cc
  7. 70
      deps/v8/src/debug-debugger.js
  8. 80
      deps/v8/src/debug.cc
  9. 37
      deps/v8/src/debug.h
  10. 2
      deps/v8/src/full-codegen.cc
  11. 6
      deps/v8/src/global-handles.cc
  12. 14
      deps/v8/src/ia32/codegen-ia32.cc
  13. 13
      deps/v8/src/ia32/debug-ia32.cc
  14. 2
      deps/v8/src/ia32/full-codegen-ia32.cc
  15. 31
      deps/v8/src/ia32/macro-assembler-ia32.cc
  16. 8
      deps/v8/src/ia32/macro-assembler-ia32.h
  17. 21
      deps/v8/src/ia32/stub-cache-ia32.cc
  18. 81
      deps/v8/src/jsregexp.cc
  19. 1
      deps/v8/src/jsregexp.h
  20. 15
      deps/v8/src/liveedit.cc
  21. 5
      deps/v8/src/mips/debug-mips.cc
  22. 32
      deps/v8/src/runtime.cc
  23. 1
      deps/v8/src/runtime.h
  24. 5
      deps/v8/src/serialize.cc
  25. 2
      deps/v8/src/unicode-inl.h
  26. 1377
      deps/v8/src/unicode.cc
  27. 1
      deps/v8/src/unicode.h
  28. 2
      deps/v8/src/v8natives.js
  29. 4
      deps/v8/src/version.cc
  30. 16
      deps/v8/src/x64/assembler-x64.cc
  31. 1
      deps/v8/src/x64/assembler-x64.h
  32. 55
      deps/v8/src/x64/codegen-x64.cc
  33. 5
      deps/v8/src/x64/debug-x64.cc
  34. 8
      deps/v8/src/x64/disasm-x64.cc
  35. 2
      deps/v8/src/x64/full-codegen-x64.cc
  36. 172
      deps/v8/src/x64/macro-assembler-x64.cc
  37. 43
      deps/v8/src/x64/macro-assembler-x64.h
  38. 81
      deps/v8/src/x64/stub-cache-x64.cc
  39. 4
      deps/v8/test/cctest/test-debug.cc
  40. 57
      deps/v8/test/cctest/test-regexp.cc
  41. 14
      deps/v8/test/mjsunit/debug-breakpoints.js
  42. 10
      deps/v8/test/mjsunit/debug-conditional-breakpoints.js
  43. 15
      deps/v8/test/mjsunit/debug-enable-disable-breakpoints.js
  44. 2
      deps/v8/test/mjsunit/debug-return-value.js
  45. 42
      deps/v8/test/mjsunit/regress/regress-784.js
  46. 51
      deps/v8/test/mjsunit/regress/regress-806.js
  47. 10
      deps/v8/tools/presubmit.py
  48. 26
      deps/v8/tools/v8.xcodeproj/project.pbxproj

25
deps/v8/ChangeLog

@ -1,3 +1,28 @@
2010-08-02: Version 2.3.4
Fixed problems in implementation of ES5 function.prototype.bind.
Fixed error when using apply with arguments object on ARM (issue 784).
Added setting of global flags to debugger protocol.
Fixed an error affecting cached results of sin and cos (issue 792).
Removed memory leak from a boundary case where V8 is not initialized.
Fixed issue where debugger could set breakpoints outside the body
of a function.
Fixed issue in debugger when using both live edit and step in features.
Added Number-letter (Nl) category to Unicode tables. These characters
can now be used in identifiers.
Fixed an assert failure on X64 (issue 806).
Performance improvements on all platforms.
2010-07-26: Version 2.3.3
Fixed error when building the d8 shell in a fresh checkout.

1
deps/v8/src/arm/codegen-arm.cc

@ -1628,6 +1628,7 @@ void CodeGenerator::CallApplyLazy(Expression* applicand,
// The function and its two arguments have been dropped.
frame_->Drop(); // Drop the receiver as well.
frame_->EmitPush(r0);
frame_->SpillAll(); // A spilled frame is also jumping to label done.
// Stack now has 1 element:
// sp[0]: result
__ bind(&done);

5
deps/v8/src/arm/debug-arm.cc

@ -296,9 +296,10 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
#undef __
void Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
UNREACHABLE();
return NULL;
}
const int Debug::kFrameDropperFrameSize = -1;

2
deps/v8/src/arm/full-codegen-arm.cc

@ -224,7 +224,7 @@ void FullCodeGenerator::EmitReturnSequence() {
// Here we use masm_-> instead of the __ macro to avoid the code coverage
// tool from instrumenting as we rely on the code size here.
int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
CodeGenerator::RecordPositions(masm_, function()->end_position());
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
__ RecordJSReturn();
masm_->mov(sp, fp);
masm_->ldm(ia_w, sp, fp.bit() | lr.bit());

5
deps/v8/src/arm/virtual-frame-arm.cc

@ -562,9 +562,10 @@ Register VirtualFrame::Peek2() {
case R1_R0_TOS:
MergeTOSTo(R1_R0_TOS);
return r0;
default:
UNREACHABLE();
return no_reg;
}
UNREACHABLE();
return no_reg;
}

2
deps/v8/src/codegen.cc

@ -433,7 +433,7 @@ void CodeGenerator::CodeForFunctionPosition(FunctionLiteral* fun) {
void CodeGenerator::CodeForReturnPosition(FunctionLiteral* fun) {
if (FLAG_debug_info) RecordPositions(masm(), fun->end_position(), false);
if (FLAG_debug_info) RecordPositions(masm(), fun->end_position() - 1, false);
}

70
deps/v8/src/debug-debugger.js

@ -79,6 +79,16 @@ var next_response_seq = 0;
var next_break_point_number = 1;
var break_points = [];
var script_break_points = [];
var debugger_flags = {
breakPointsActive: {
value: true,
getValue: function() { return this.value; },
setValue: function(value) {
this.value = !!value;
%SetDisableBreak(!this.value);
}
}
};
// Create a new break point object and add it to the list of break points.
@ -246,7 +256,7 @@ ScriptBreakPoint.prototype.cloneForOtherScript = function (other_script) {
other_script.id, this.line_, this.column_, this.groupId_);
copy.number_ = next_break_point_number++;
script_break_points.push(copy);
copy.hit_count_ = this.hit_count_;
copy.active_ = this.active_;
copy.condition_ = this.condition_;
@ -813,7 +823,13 @@ Debug.showBreakPoints = function(f, full) {
Debug.scripts = function() {
// Collect all scripts in the heap.
return %DebugGetLoadedScripts();
}
};
Debug.debuggerFlags = function() {
return debugger_flags;
};
function MakeExecutionState(break_id) {
return new ExecutionState(break_id);
@ -1325,9 +1341,11 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(json_request)
} else if (request.command == 'version') {
this.versionRequest_(request, response);
} else if (request.command == 'profile') {
this.profileRequest_(request, response);
this.profileRequest_(request, response);
} else if (request.command == 'changelive') {
this.changeLiveRequest_(request, response);
this.changeLiveRequest_(request, response);
} else if (request.command == 'flags') {
this.debuggerFlagsRequest_(request, response);
} else {
throw new Error('Unknown command "' + request.command + '" in request');
}
@ -1617,6 +1635,7 @@ DebugCommandProcessor.prototype.clearBreakPointRequest_ = function(request, resp
response.body = { breakpoint: break_point }
}
DebugCommandProcessor.prototype.listBreakpointsRequest_ = function(request, response) {
var array = [];
for (var i = 0; i < script_break_points.length; i++) {
@ -1633,7 +1652,7 @@ DebugCommandProcessor.prototype.listBreakpointsRequest_ = function(request, resp
ignoreCount: break_point.ignoreCount(),
actual_locations: break_point.actual_locations()
}
if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {
description.type = 'scriptId';
description.script_id = break_point.script_id();
@ -1643,7 +1662,7 @@ DebugCommandProcessor.prototype.listBreakpointsRequest_ = function(request, resp
}
array.push(description);
}
response.body = { breakpoints: array }
}
@ -2086,7 +2105,7 @@ DebugCommandProcessor.prototype.changeLiveRequest_ = function(request, response)
}
var change_log = new Array();
if (!IS_STRING(request.arguments.new_source)) {
throw "new_source argument expected";
}
@ -2096,9 +2115,46 @@ DebugCommandProcessor.prototype.changeLiveRequest_ = function(request, response)
var result_description = Debug.LiveEdit.SetScriptSource(the_script,
new_source, preview_only, change_log);
response.body = {change_log: change_log, result: result_description};
if (!preview_only && !this.running_ && result_description.stack_modified) {
response.body.stepin_recommended = true;
}
};
DebugCommandProcessor.prototype.debuggerFlagsRequest_ = function(request,
response) {
// Check for legal request.
if (!request.arguments) {
response.failed('Missing arguments');
return;
}
// Pull out arguments.
var flags = request.arguments.flags;
response.body = { flags: [] };
if (!IS_UNDEFINED(flags)) {
for (var i = 0; i < flags.length; i++) {
var name = flags[i].name;
var debugger_flag = debugger_flags[name];
if (!debugger_flag) {
continue;
}
if ('value' in flags[i]) {
debugger_flag.setValue(flags[i].value);
}
response.body.flags.push({ name: name, value: debugger_flag.getValue() });
}
} else {
for (var name in debugger_flags) {
var value = debugger_flags[name].getValue();
response.body.flags.push({ name: name, value: value });
}
}
}
// Check whether the previously processed command caused the VM to become
// running.
DebugCommandProcessor.prototype.isRunning = function() {

80
deps/v8/src/debug.cc

@ -170,7 +170,7 @@ void BreakLocationIterator::Next() {
// Set the positions to the end of the function.
if (debug_info_->shared()->HasSourceCode()) {
position_ = debug_info_->shared()->end_position() -
debug_info_->shared()->start_position();
debug_info_->shared()->start_position() - 1;
} else {
position_ = 0;
}
@ -1224,36 +1224,42 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
it.FindBreakLocationFromAddress(frame->pc());
// Compute whether or not the target is a call target.
bool is_call_target = false;
bool is_load_or_store = false;
bool is_inline_cache_stub = false;
bool is_at_restarted_function = false;
Handle<Code> call_function_stub;
if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
Address target = it.rinfo()->target_address();
Code* code = Code::GetCodeFromTargetAddress(target);
if (code->is_call_stub() || code->is_keyed_call_stub()) {
is_call_target = true;
}
if (code->is_inline_cache_stub()) {
is_inline_cache_stub = true;
is_load_or_store = !is_call_target;
}
// Check if target code is CallFunction stub.
Code* maybe_call_function_stub = code;
// If there is a breakpoint at this line look at the original code to
// check if it is a CallFunction stub.
if (it.IsDebugBreak()) {
Address original_target = it.original_rinfo()->target_address();
maybe_call_function_stub =
Code::GetCodeFromTargetAddress(original_target);
}
if (maybe_call_function_stub->kind() == Code::STUB &&
maybe_call_function_stub->major_key() == CodeStub::CallFunction) {
// Save reference to the code as we may need it to find out arguments
// count for 'step in' later.
call_function_stub = Handle<Code>(maybe_call_function_stub);
if (thread_local_.restarter_frame_function_pointer_ == NULL) {
if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) {
bool is_call_target = false;
Address target = it.rinfo()->target_address();
Code* code = Code::GetCodeFromTargetAddress(target);
if (code->is_call_stub() || code->is_keyed_call_stub()) {
is_call_target = true;
}
if (code->is_inline_cache_stub()) {
is_inline_cache_stub = true;
is_load_or_store = !is_call_target;
}
// Check if target code is CallFunction stub.
Code* maybe_call_function_stub = code;
// If there is a breakpoint at this line look at the original code to
// check if it is a CallFunction stub.
if (it.IsDebugBreak()) {
Address original_target = it.original_rinfo()->target_address();
maybe_call_function_stub =
Code::GetCodeFromTargetAddress(original_target);
}
if (maybe_call_function_stub->kind() == Code::STUB &&
maybe_call_function_stub->major_key() == CodeStub::CallFunction) {
// Save reference to the code as we may need it to find out arguments
// count for 'step in' later.
call_function_stub = Handle<Code>(maybe_call_function_stub);
}
}
} else {
is_at_restarted_function = true;
}
// If this is the last break code target step out is the only possibility.
@ -1282,7 +1288,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
ActivateStepOut(frames_it.frame());
}
} else if (!(is_inline_cache_stub || RelocInfo::IsConstructCall(it.rmode()) ||
!call_function_stub.is_null())
!call_function_stub.is_null() || is_at_restarted_function)
|| step_action == StepNext || step_action == StepMin) {
// Step next or step min.
@ -1294,9 +1300,18 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
debug_info->code()->SourceStatementPosition(frame->pc());
thread_local_.last_fp_ = frame->fp();
} else {
// If it's CallFunction stub ensure target function is compiled and flood
// it with one shot breakpoints.
if (!call_function_stub.is_null()) {
// If there's restarter frame on top of the stack, just get the pointer
// to function which is going to be restarted.
if (is_at_restarted_function) {
Handle<JSFunction> restarted_function(
JSFunction::cast(*thread_local_.restarter_frame_function_pointer_));
Handle<SharedFunctionInfo> restarted_shared(
restarted_function->shared());
FloodWithOneShot(restarted_shared);
} else if (!call_function_stub.is_null()) {
// If it's CallFunction stub ensure target function is compiled and flood
// it with one shot breakpoints.
// Find out number of arguments from the stub minor key.
// Reverse lookup required as the minor key cannot be retrieved
// from the code object.
@ -1767,9 +1782,12 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
FrameDropMode mode) {
FrameDropMode mode,
Object** restarter_frame_function_pointer) {
thread_local_.frame_drop_mode_ = mode;
thread_local_.break_frame_id_ = new_break_frame_id;
thread_local_.restarter_frame_function_pointer_ =
restarter_frame_function_pointer;
}

37
deps/v8/src/debug.h

@ -332,6 +332,7 @@ class Debug {
k_after_break_target_address,
k_debug_break_return_address,
k_debug_break_slot_address,
k_restarter_frame_function_pointer,
k_register_address
};
@ -339,6 +340,10 @@ class Debug {
static Address* after_break_target_address() {
return reinterpret_cast<Address*>(&thread_local_.after_break_target_);
}
static Address* restarter_frame_function_pointer_address() {
Object*** address = &thread_local_.restarter_frame_function_pointer_;
return reinterpret_cast<Address*>(address);
}
// Support for saving/restoring registers when handling debug break calls.
static Object** register_address(int r) {
@ -415,10 +420,22 @@ class Debug {
};
static void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
FrameDropMode mode);
FrameDropMode mode,
Object** restarter_frame_function_pointer);
// Initializes an artificial stack frame. The data it contains is used for:
// a. successful work of frame dropper code which eventually gets control,
// b. being compatible with regular stack structure for various stack
// iterators.
// Returns address of stack allocated pointer to restarted function,
// the value that is called 'restarter_frame_function_pointer'. The value
// at this address (possibly updated by GC) may be used later when preparing
// 'step in' operation.
// The implementation is architecture-specific.
// TODO(LiveEdit): consider reviewing it as architecture-independent.
static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code);
static void SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code);
static const int kFrameDropperFrameSize;
private:
@ -495,6 +512,11 @@ class Debug {
// Pending interrupts scheduled while debugging.
int pending_interrupts_;
// When restarter frame is on stack, stores the address
// of the pointer to function being restarted. Otherwise (most of the time)
// stores NULL. This pointer is used with 'step in' implementation.
Object** restarter_frame_function_pointer_;
};
// Storage location for registers when handling debug break calls
@ -906,8 +928,6 @@ class EnterDebugger BASE_EMBEDDED {
// Stack allocated class for disabling break.
class DisableBreak BASE_EMBEDDED {
public:
// Enter the debugger by storing the previous top context and setting the
// current top context to the debugger context.
explicit DisableBreak(bool disable_break) {
prev_disable_break_ = Debug::disable_break();
Debug::set_disable_break(disable_break);
@ -940,6 +960,10 @@ class Debug_Address {
return Debug_Address(Debug::k_debug_break_return_address);
}
static Debug_Address RestarterFrameFunctionPointer() {
return Debug_Address(Debug::k_restarter_frame_function_pointer);
}
static Debug_Address Register(int reg) {
return Debug_Address(Debug::k_register_address, reg);
}
@ -952,6 +976,9 @@ class Debug_Address {
return reinterpret_cast<Address>(Debug::debug_break_return_address());
case Debug::k_debug_break_slot_address:
return reinterpret_cast<Address>(Debug::debug_break_slot_address());
case Debug::k_restarter_frame_function_pointer:
return reinterpret_cast<Address>(
Debug::restarter_frame_function_pointer_address());
case Debug::k_register_address:
return reinterpret_cast<Address>(Debug::register_address(reg_));
default:

2
deps/v8/src/full-codegen.cc

@ -770,7 +770,7 @@ void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
if (FLAG_debug_info) {
CodeGenerator::RecordPositions(masm_, fun->end_position());
CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
}
}

6
deps/v8/src/global-handles.cc

@ -226,6 +226,12 @@ class GlobalHandles::Pool BASE_EMBEDDED {
limit_ = current_->nodes + kNodesPerChunk;
}
~Pool() {
if (current_ != NULL) {
Release();
}
}
Node* Allocate() {
if (next_ < limit_) {
return next_++;

14
deps/v8/src/ia32/codegen-ia32.cc

@ -12275,7 +12275,7 @@ static const bool kPassHandlesDirectly = false;
void ApiGetterEntryStub::Generate(MacroAssembler* masm) {
Label get_result;
Label empty_handle;
Label prologue;
Label promote_scheduled_exception;
__ EnterApiExitFrame(ExitFrame::MODE_NORMAL, kStackSpace, kArgc);
@ -12318,20 +12318,20 @@ void ApiGetterEntryStub::Generate(MacroAssembler* masm) {
// Dereference this to get to the location.
__ mov(eax, Operand(eax, 0));
}
// Check if the result handle holds 0
// Check if the result handle holds 0.
__ test(eax, Operand(eax));
__ j(not_zero, &get_result, taken);
// It was zero; the result is undefined.
__ mov(eax, Factory::undefined_value());
__ jmp(&prologue);
__ j(zero, &empty_handle, not_taken);
// It was non-zero. Dereference to get the result value.
__ bind(&get_result);
__ mov(eax, Operand(eax, 0));
__ bind(&prologue);
__ LeaveExitFrame(ExitFrame::MODE_NORMAL);
__ ret(0);
__ bind(&promote_scheduled_exception);
__ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
__ bind(&empty_handle);
// It was zero; the result is undefined.
__ mov(eax, Factory::undefined_value());
__ jmp(&prologue);
}

13
deps/v8/src/ia32/debug-ia32.cc

@ -265,6 +265,10 @@ void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
// -- context
// -- frame base
void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
ExternalReference restarter_frame_function_slot =
ExternalReference(Debug_Address::RestarterFrameFunctionPointer());
__ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
// We do not know our frame height, but set esp based on ebp.
__ lea(esp, Operand(ebp, -4 * kPointerSize));
@ -288,8 +292,10 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
#undef __
void Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
// TODO(LiveEdit): consider making it platform-independent.
// TODO(LiveEdit): use more named constants instead of numbers.
Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
ASSERT(bottom_js_frame->is_java_script());
Address fp = bottom_js_frame->fp();
@ -298,7 +304,10 @@ void Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Memory::Object_at(fp - 3 * kPointerSize) = *code;
Memory::Object_at(fp - 2 * kPointerSize) = Smi::FromInt(StackFrame::INTERNAL);
return reinterpret_cast<Object**>(&Memory::Object_at(fp - 4 * kPointerSize));
}
const int Debug::kFrameDropperFrameSize = 5;

2
deps/v8/src/ia32/full-codegen-ia32.cc

@ -207,7 +207,7 @@ void FullCodeGenerator::EmitReturnSequence() {
Label check_exit_codesize;
masm_->bind(&check_exit_codesize);
#endif
CodeGenerator::RecordPositions(masm_, function()->end_position());
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
__ RecordJSReturn();
// Do not use the leave instruction here because it is too short to
// patch with the code required by the debugger.

31
deps/v8/src/ia32/macro-assembler-ia32.cc

@ -1052,16 +1052,6 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
}
void MacroAssembler::CallExternalReference(ExternalReference ref,
int num_arguments) {
mov(eax, Immediate(num_arguments));
mov(ebx, Immediate(ref));
CEntryStub stub(1);
CallStub(&stub);
}
Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
int num_arguments) {
if (f->nargs >= 0 && f->nargs != num_arguments) {
@ -1082,6 +1072,16 @@ Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
}
void MacroAssembler::CallExternalReference(ExternalReference ref,
int num_arguments) {
mov(eax, Immediate(num_arguments));
mov(ebx, Immediate(ref));
CEntryStub stub(1);
CallStub(&stub);
}
void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
int num_arguments,
int result_size) {
@ -1106,8 +1106,7 @@ void MacroAssembler::PushHandleScope(Register scratch) {
ExternalReference extensions_address =
ExternalReference::handle_scope_extensions_address();
mov(scratch, Operand::StaticVariable(extensions_address));
ASSERT_EQ(0, kSmiTag);
shl(scratch, kSmiTagSize);
SmiTag(scratch);
push(scratch);
mov(Operand::StaticVariable(extensions_address), Immediate(0));
// Push next and limit pointers which will be wordsize aligned and
@ -1131,16 +1130,14 @@ Object* MacroAssembler::PopHandleScopeHelper(Register saved,
mov(scratch, Operand::StaticVariable(extensions_address));
cmp(Operand(scratch), Immediate(0));
j(equal, &write_back);
// Calling a runtime function messes with registers so we save and
// restore any one we're asked not to change
if (saved.is_valid()) push(saved);
push(saved);
if (gc_allowed) {
CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
} else {
result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
if (result->IsFailure()) return result;
}
if (saved.is_valid()) pop(saved);
pop(saved);
bind(&write_back);
ExternalReference limit_address =
@ -1150,7 +1147,7 @@ Object* MacroAssembler::PopHandleScopeHelper(Register saved,
ExternalReference::handle_scope_next_address();
pop(Operand::StaticVariable(next_address));
pop(scratch);
shr(scratch, kSmiTagSize);
SmiUntag(scratch);
mov(Operand::StaticVariable(extensions_address), scratch);
return result;

8
deps/v8/src/ia32/macro-assembler-ia32.h

@ -393,12 +393,12 @@ class MacroAssembler: public Assembler {
// Convenience function: Same as above, but takes the fid instead.
void CallRuntime(Runtime::FunctionId id, int num_arguments);
// Convenience function: call an external reference.
void CallExternalReference(ExternalReference ref, int num_arguments);
// Convenience function: Same as above, but takes the fid instead.
Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
// Convenience function: call an external reference.
void CallExternalReference(ExternalReference ref, int num_arguments);
// Tail call of a runtime routine (jump).
// Like JumpToExternalReference, but also takes care of passing the number
// of parameters.
@ -431,7 +431,7 @@ class MacroAssembler: public Assembler {
void PushHandleScope(Register scratch);
// Pops a handle scope using the specified scratch register and
// ensuring that saved register, it is not no_reg, is left unchanged.
// ensuring that saved register is left unchanged.
void PopHandleScope(Register saved, Register scratch);
// As PopHandleScope, but does not perform a GC. Instead, returns a

21
deps/v8/src/ia32/stub-cache-ia32.cc

@ -1033,24 +1033,23 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object,
// Check that the maps haven't changed.
Register reg =
CheckPrototypes(object, receiver, holder,
scratch1, scratch2, scratch3, name, miss);
CheckPrototypes(object, receiver, holder, scratch1,
scratch2, scratch3, name, miss);
Handle<AccessorInfo> callback_handle(callback);
Register other = reg.is(scratch1) ? scratch2 : scratch1;
__ EnterInternalFrame();
__ PushHandleScope(other);
// Push the stack address where the list of arguments ends
__ mov(other, esp);
__ sub(Operand(other), Immediate(2 * kPointerSize));
__ push(other);
__ PushHandleScope(scratch2);
// Push the stack address where the list of arguments ends.
__ mov(scratch2, esp);
__ sub(Operand(scratch2), Immediate(2 * kPointerSize));
__ push(scratch2);
__ push(receiver); // receiver
__ push(reg); // holder
// Push data from AccessorInfo.
if (Heap::InNewSpace(callback_handle->data())) {
__ mov(other, Immediate(callback_handle));
__ push(FieldOperand(other, AccessorInfo::kDataOffset));
__ mov(scratch2, Immediate(callback_handle));
__ push(FieldOperand(scratch2, AccessorInfo::kDataOffset));
} else {
__ push(Immediate(Handle<Object>(callback_handle->data())));
}
@ -1077,7 +1076,7 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object,
}
// We need to avoid using eax since that now holds the result.
Register tmp = other.is(eax) ? reg : other;
Register tmp = scratch2.is(eax) ? reg : scratch2;
// Emitting PopHandleScope may try to allocate. Do not allow the
// assembler to perform a garbage collection but instead return a
// failure object.

81
deps/v8/src/jsregexp.cc

@ -1272,7 +1272,7 @@ static int GetCaseIndependentLetters(uc16 character,
bool ascii_subject,
unibrow::uchar* letters) {
int length = uncanonicalize.get(character, '\0', letters);
// Unibrow returns 0 or 1 for characters where case independependence is
// Unibrow returns 0 or 1 for characters where case independence is
// trivial.
if (length == 0) {
letters[0] = character;
@ -4026,74 +4026,48 @@ void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
ranges->Add(CharacterRange::Singleton(chars[i]));
}
}
} else if (bottom <= kRangeCanonicalizeMax &&
top <= kRangeCanonicalizeMax) {
} else {
// If this is a range we expand the characters block by block,
// expanding contiguous subranges (blocks) one at a time.
// The approach is as follows. For a given start character we
// look up the block that contains it, for instance 'a' if the
// start character is 'c'. A block is characterized by the property
// that all characters uncanonicalize in the same way as the first
// element, except that each entry in the result is incremented
// by the distance from the first element. So a-z is a block
// because 'a' uncanonicalizes to ['a', 'A'] and the k'th letter
// uncanonicalizes to ['a' + k, 'A' + k].
// Once we've found the start point we look up its uncanonicalization
// look up the remainder of the block that contains it (represented
// by the end point), for instance we find 'z' if the character
// is 'c'. A block is characterized by the property
// that all characters uncanonicalize in the same way, except that
// each entry in the result is incremented by the distance from the first
// element. So a-z is a block because 'a' uncanonicalizes to ['a', 'A'] and
// the k'th letter uncanonicalizes to ['a' + k, 'A' + k].
// Once we've found the end point we look up its uncanonicalization
// and produce a range for each element. For instance for [c-f]
// we look up ['a', 'A'] and produce [c-f] and [C-F]. We then only
// we look up ['z', 'Z'] and produce [c-f] and [C-F]. We then only
// add a range if it is not already contained in the input, so [c-f]
// will be skipped but [C-F] will be added. If this range is not
// completely contained in a block we do this for all the blocks
// covered by the range.
// covered by the range (handling characters that is not in a block
// as a "singleton block").
unibrow::uchar range[unibrow::Ecma262UnCanonicalize::kMaxWidth];
// First, look up the block that contains the 'bottom' character.
int length = canonrange.get(bottom, '\0', range);
if (length == 0) {
range[0] = bottom;
} else {
ASSERT_EQ(1, length);
}
int pos = bottom;
// The start of the current block. Note that except for the first
// iteration 'start' is always equal to 'pos'.
int start;
// If it is not the start point of a block the entry contains the
// offset of the character from the start point.
if ((range[0] & kStartMarker) == 0) {
start = pos - range[0];
} else {
start = pos;
}
// Then we add the ranges one at a time, incrementing the current
// position to be after the last block each time. The position
// always points to the start of a block.
while (pos < top) {
length = canonrange.get(start, '\0', range);
int length = canonrange.get(pos, '\0', range);
uc16 block_end;
if (length == 0) {
range[0] = start;
block_end = pos;
} else {
ASSERT_EQ(1, length);
block_end = range[0];
}
ASSERT((range[0] & kStartMarker) != 0);
// The start point of a block contains the distance to the end
// of the range.
int block_end = start + (range[0] & kPayloadMask) - 1;
int end = (block_end > top) ? top : block_end;
length = uncanonicalize.get(start, '\0', range);
length = uncanonicalize.get(block_end, '\0', range);
for (int i = 0; i < length; i++) {
uc32 c = range[i];
uc16 range_from = c + (pos - start);
uc16 range_to = c + (end - start);
uc16 range_from = c - (block_end - pos);
uc16 range_to = c - (block_end - end);
if (!(bottom <= range_from && range_to <= top)) {
ranges->Add(CharacterRange(range_from, range_to));
}
}
start = pos = block_end + 1;
pos = end + 1;
}
} else {
// Unibrow ranges don't work for high characters due to the "2^11 bug".
// Therefore we do something dumber for these ranges.
AddUncanonicals(ranges, bottom, top);
}
}
@ -4208,20 +4182,14 @@ static void AddUncanonicals(ZoneList<CharacterRange>* ranges,
// 0xa800 - 0xfaff
// 0xfc00 - 0xfeff
const int boundary_count = 18;
// The ASCII boundary and the kRangeCanonicalizeMax boundary are also in this
// array. This is to split up big ranges and not because they actually denote
// a case-mapping-free-zone.
ASSERT(CharacterRange::kRangeCanonicalizeMax < 0x600);
const int kFirstRealCaselessZoneIndex = 2;
int boundaries[] = {0x80, CharacterRange::kRangeCanonicalizeMax,
int boundaries[] = {
0x600, 0x1000, 0x1100, 0x1d00, 0x2000, 0x2100, 0x2200, 0x2400, 0x2500,
0x2c00, 0x2e00, 0xa600, 0xa800, 0xfb00, 0xfc00, 0xff00};
// Special ASCII rule from spec can save us some work here.
if (bottom == 0x80 && top == 0xffff) return;
// We have optimized support for this range.
if (top <= CharacterRange::kRangeCanonicalizeMax) {
if (top <= boundaries[0]) {
CharacterRange range(bottom, top);
range.AddCaseEquivalents(ranges, false);
return;
@ -4238,8 +4206,7 @@ static void AddUncanonicals(ZoneList<CharacterRange>* ranges,
}
// If we are completely in a zone with no case mappings then we are done.
// We start at 2 so as not to except the ASCII range from mappings.
for (int i = kFirstRealCaselessZoneIndex; i < boundary_count; i += 2) {
for (int i = 0; i < boundary_count; i += 2) {
if (bottom >= boundaries[i] && top < boundaries[i + 1]) {
#ifdef DEBUG
for (int j = bottom; j <= top; j++) {

1
deps/v8/src/jsregexp.h

@ -316,7 +316,6 @@ class CharacterRange {
// Negate the contents of a character range in canonical form.
static void Negate(ZoneList<CharacterRange>* src,
ZoneList<CharacterRange>* dst);
static const int kRangeCanonicalizeMax = 0x346;
static const int kStartMarker = (1 << 24);
static const int kPayloadMask = (1 << 24) - 1;

15
deps/v8/src/liveedit.cc

@ -1188,7 +1188,8 @@ static bool FixTryCatchHandler(StackFrame* top_frame,
static const char* DropFrames(Vector<StackFrame*> frames,
int top_frame_index,
int bottom_js_frame_index,
Debug::FrameDropMode* mode) {
Debug::FrameDropMode* mode,
Object*** restarter_frame_function_pointer) {
if (Debug::kFrameDropperFrameSize < 0) {
return "Stack manipulations are not supported in this architecture.";
}
@ -1238,7 +1239,10 @@ static const char* DropFrames(Vector<StackFrame*> frames,
top_frame->set_pc(code->entry());
pre_top_frame->SetCallerFp(bottom_js_frame->fp());
Debug::SetUpFrameDropperFrame(bottom_js_frame, code);
*restarter_frame_function_pointer =
Debug::SetUpFrameDropperFrame(bottom_js_frame, code);
ASSERT((**restarter_frame_function_pointer)->IsJSFunction());
for (Address a = unused_stack_top;
a < unused_stack_bottom;
@ -1328,8 +1332,10 @@ static const char* DropActivationsInActiveThread(
}
Debug::FrameDropMode drop_mode = Debug::FRAMES_UNTOUCHED;
Object** restarter_frame_function_pointer = NULL;
const char* error_message = DropFrames(frames, top_frame_index,
bottom_js_frame_index, &drop_mode);
bottom_js_frame_index, &drop_mode,
&restarter_frame_function_pointer);
if (error_message != NULL) {
return error_message;
@ -1343,7 +1349,8 @@ static const char* DropActivationsInActiveThread(
break;
}
}
Debug::FramesHaveBeenDropped(new_id, drop_mode);
Debug::FramesHaveBeenDropped(new_id, drop_mode,
restarter_frame_function_pointer);
// Replace "blocked on active" with "replaced on active" status.
for (int i = 0; i < array_len; i++) {

5
deps/v8/src/mips/debug-mips.cc

@ -117,9 +117,10 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
#undef __
void Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
UNREACHABLE();
return NULL;
}
const int Debug::kFrameDropperFrameSize = -1;

32
deps/v8/src/runtime.cc

@ -6757,17 +6757,23 @@ static Object* Runtime_NewObjectFromBound(Arguments args) {
CONVERT_ARG_CHECKED(JSFunction, function, 0);
CONVERT_ARG_CHECKED(JSArray, params, 1);
RUNTIME_ASSERT(params->HasFastElements());
FixedArray* fixed = FixedArray::cast(params->elements());
bool exception = false;
Object*** param_data = NewArray<Object**>(fixed->length());
for (int i = 0; i < fixed->length(); i++) {
int fixed_length = Smi::cast(params->length())->value();
SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length));
for (int i = 0; i < fixed_length; i++) {
Handle<Object> val = Handle<Object>(fixed->get(i));
param_data[i] = val.location();
}
bool exception = false;
Handle<Object> result = Execution::New(
function, fixed->length(), param_data, &exception);
function, fixed_length, *param_data, &exception);
if (exception) {
return Failure::Exception();
}
ASSERT(!result.is_null());
return *result;
}
@ -9237,6 +9243,17 @@ static Object* Runtime_GetThreadDetails(Arguments args) {
}
// Sets the disable break state
// args[0]: disable break state
static Object* Runtime_SetDisableBreak(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 1);
CONVERT_BOOLEAN_CHECKED(disable_break, args[0]);
Debug::set_disable_break(disable_break);
return Heap::undefined_value();
}
static Object* Runtime_GetBreakLocations(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 1);
@ -9381,13 +9398,6 @@ static Object* Runtime_SetScriptBreakPoint(Arguments args) {
}
Debug::SetBreakPoint(shared, break_point_object_arg, &position);
position += shared->start_position();
// The result position may become beyond script source end.
// This is expected when the function is toplevel. This may become
// a problem later when actual position gets converted into line/column.
if (shared->is_toplevel() && position == shared->end_position()) {
position = shared->end_position() - 1;
}
return Smi::FromInt(position);
}
return Heap::undefined_value();

1
deps/v8/src/runtime.h

@ -322,6 +322,7 @@ namespace internal {
F(GetCFrames, 1, 1) \
F(GetThreadCount, 1, 1) \
F(GetThreadDetails, 2, 1) \
F(SetDisableBreak, 1, 1) \
F(GetBreakLocations, 1, 1) \
F(SetFunctionBreakPoint, 3, 1) \
F(SetScriptBreakPoint, 3, 1) \

5
deps/v8/src/serialize.cc

@ -237,6 +237,10 @@ void ExternalReferenceTable::PopulateTable() {
DEBUG_ADDRESS,
Debug::k_debug_break_return_address << kDebugIdShift,
"Debug::debug_break_return_address()");
Add(Debug_Address(Debug::k_restarter_frame_function_pointer).address(),
DEBUG_ADDRESS,
Debug::k_restarter_frame_function_pointer << kDebugIdShift,
"Debug::restarter_frame_function_pointer_address()");
const char* debug_register_format = "Debug::register_address(%i)";
int dr_format_length = StrLength(debug_register_format);
for (int i = 0; i < kNumJSCallerSaved; ++i) {
@ -478,6 +482,7 @@ ExternalReferenceEncoder::ExternalReferenceEncoder()
uint32_t ExternalReferenceEncoder::Encode(Address key) const {
int index = IndexOf(key);
ASSERT(key == NULL || index >= 0);
return index >=0 ? ExternalReferenceTable::instance()->code(index) : 0;
}

2
deps/v8/src/unicode-inl.h

@ -1,4 +1,4 @@
// Copyright 2007-2008 the V8 project authors. All rights reserved.
// Copyright 2007-2010 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:

1377
deps/v8/src/unicode.cc

File diff suppressed because one or more lines are too long

1
deps/v8/src/unicode.h

@ -211,6 +211,7 @@ class Utf8InputBuffer : public InputBuffer<Utf8, Buffer<const char*>, s> {
}
};
struct Uppercase {
static bool Is(uchar c);
};

2
deps/v8/src/v8natives.js

@ -1105,7 +1105,7 @@ function FunctionBind(this_arg) { // Length is 1.
throw new $TypeError('Bind must be called on a function');
}
// this_arg is not an argument that should be bound.
var argc_bound = %_ArgumentsLength() - 1;
var argc_bound = (%_ArgumentsLength() || 1) - 1;
if (argc_bound > 0) {
var bound_args = new $Array(argc_bound);
for(var i = 0; i < argc_bound; i++) {

4
deps/v8/src/version.cc

@ -34,8 +34,8 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 2
#define MINOR_VERSION 3
#define BUILD_NUMBER 3
#define PATCH_LEVEL 0
#define BUILD_NUMBER 4
#define PATCH_LEVEL 1
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the

16
deps/v8/src/x64/assembler-x64.cc

@ -1496,12 +1496,8 @@ void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
void Assembler::movq(Register dst, ExternalReference ref) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_rex_64(dst);
emit(0xB8 | dst.low_bits());
emitq(reinterpret_cast<uintptr_t>(ref.address()),
RelocInfo::EXTERNAL_REFERENCE);
int64_t value = reinterpret_cast<int64_t>(ref.address());
movq(dst, value, RelocInfo::EXTERNAL_REFERENCE);
}
@ -2529,10 +2525,10 @@ void Assembler::movd(Register dst, XMMRegister src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit(0x66);
emit_optional_rex_32(dst, src);
emit_optional_rex_32(src, dst);
emit(0x0F);
emit(0x7E);
emit_sse_operand(dst, src);
emit_sse_operand(src, dst);
}
@ -2551,10 +2547,10 @@ void Assembler::movq(Register dst, XMMRegister src) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit(0x66);
emit_rex_64(dst, src);
emit_rex_64(src, dst);
emit(0x0F);
emit(0x7E);
emit_sse_operand(dst, src);
emit_sse_operand(src, dst);
}

1
deps/v8/src/x64/assembler-x64.h

@ -509,7 +509,6 @@ class Assembler : public Malloced {
void push(Immediate value);
void push(Register src);
void push(const Operand& src);
void push(Label* label, RelocInfo::Mode relocation_mode);
void pop(Register dst);
void pop(const Operand& dst);

55
deps/v8/src/x64/codegen-x64.cc

@ -8071,6 +8071,18 @@ Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
result = allocator()->Allocate();
ASSERT(result.is_valid() && receiver.is_valid() && value.is_valid());
// Cannot use r12 for receiver, because that changes
// the distance between a call and a fixup location,
// due to a special encoding of r12 as r/m in a ModR/M byte.
if (receiver.reg().is(r12)) {
frame()->Spill(receiver.reg()); // It will be overwritten with result.
// Swap receiver and value.
__ movq(result.reg(), receiver.reg());
Result temp = receiver;
receiver = result;
result = temp;
}
// Check that the receiver is a heap object.
Condition is_smi = __ CheckSmi(receiver.reg());
slow.Branch(is_smi, &value, &receiver);
@ -10890,7 +10902,48 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
void ApiGetterEntryStub::Generate(MacroAssembler* masm) {
UNREACHABLE();
Label empty_result;
Label prologue;
Label promote_scheduled_exception;
__ EnterApiExitFrame(ExitFrame::MODE_NORMAL, kStackSpace, 0);
ASSERT_EQ(kArgc, 4);
#ifdef _WIN64
// All the parameters should be set up by a caller.
#else
// Set 1st parameter register with property name.
__ movq(rsi, rdx);
// Second parameter register rdi should be set with pointer to AccessorInfo
// by a caller.
#endif
// Call the api function!
__ movq(rax,
reinterpret_cast<int64_t>(fun()->address()),
RelocInfo::RUNTIME_ENTRY);
__ call(rax);
// Check if the function scheduled an exception.
ExternalReference scheduled_exception_address =
ExternalReference::scheduled_exception_address();
__ movq(rsi, scheduled_exception_address);
__ Cmp(Operand(rsi, 0), Factory::the_hole_value());
__ j(not_equal, &promote_scheduled_exception);
#ifdef _WIN64
// rax keeps a pointer to v8::Handle, unpack it.
__ movq(rax, Operand(rax, 0));
#endif
// Check if the result handle holds 0.
__ testq(rax, rax);
__ j(zero, &empty_result);
// It was non-zero. Dereference to get the result value.
__ movq(rax, Operand(rax, 0));
__ bind(&prologue);
__ LeaveExitFrame(ExitFrame::MODE_NORMAL);
__ ret(0);
__ bind(&promote_scheduled_exception);
__ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
__ bind(&empty_result);
// It was zero; the result is undefined.
__ Move(rax, Factory::undefined_value());
__ jmp(&prologue);
}

5
deps/v8/src/x64/debug-x64.cc

@ -213,9 +213,10 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
#undef __
void Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code) {
UNREACHABLE();
return NULL;
}
const int Debug::kFrameDropperFrameSize = -1;

8
deps/v8/src/x64/disasm-x64.cc

@ -1019,10 +1019,10 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
NameOfXMMRegister(regop));
current += PrintRightOperand(current);
} else if (opcode == 0x7E) {
AppendToBuffer("mov%c %s,",
rex_w() ? 'q' : 'd',
NameOfCPURegister(regop));
current += PrintRightXMMOperand(current);
AppendToBuffer("mov%c ",
rex_w() ? 'q' : 'd');
current += PrintRightOperand(current);
AppendToBuffer(", %s", NameOfXMMRegister(regop));
} else {
const char* mnemonic = "?";
if (opcode == 0x57) {

2
deps/v8/src/x64/full-codegen-x64.cc

@ -207,7 +207,7 @@ void FullCodeGenerator::EmitReturnSequence() {
Label check_exit_codesize;
masm_->bind(&check_exit_codesize);
#endif
CodeGenerator::RecordPositions(masm_, function()->end_position());
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
__ RecordJSReturn();
// Do not use the leave instruction here because it is too short to
// patch with the code required by the debugger.

172
deps/v8/src/x64/macro-assembler-x64.cc

@ -336,12 +336,32 @@ void MacroAssembler::CallStub(CodeStub* stub) {
}
Object* MacroAssembler::TryCallStub(CodeStub* stub) {
ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
Object* result = stub->TryGetCode();
if (!result->IsFailure()) {
call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
}
return result;
}
void MacroAssembler::TailCallStub(CodeStub* stub) {
ASSERT(allow_stub_calls()); // calls are not allowed in some stubs
Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
}
Object* MacroAssembler::TryTailCallStub(CodeStub* stub) {
ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
Object* result = stub->TryGetCode();
if (!result->IsFailure()) {
jmp(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
}
return result;
}
void MacroAssembler::StubReturn(int argc) {
ASSERT(argc >= 1 && generating_stub());
ret((argc - 1) * kPointerSize);
@ -361,6 +381,12 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
}
Object* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
int num_arguments) {
return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
}
void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
// If the expected number of arguments of the runtime function is
// constant, we check that the actual number of arguments match the
@ -381,6 +407,26 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
}
Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
int num_arguments) {
if (f->nargs >= 0 && f->nargs != num_arguments) {
IllegalOperation(num_arguments);
// Since we did not call the stub, there was no allocation failure.
// Return some non-failure object.
return Heap::undefined_value();
}
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
// should remove this need and make the runtime routine entry code
// smarter.
Set(rax, num_arguments);
movq(rbx, ExternalReference(f));
CEntryStub ces(f->result_size);
return TryCallStub(&ces);
}
void MacroAssembler::CallExternalReference(const ExternalReference& ext,
int num_arguments) {
Set(rax, num_arguments);
@ -417,6 +463,87 @@ void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
}
static int Offset(ExternalReference ref0, ExternalReference ref1) {
int64_t offset = (ref0.address() - ref1.address());
// Check that fits into int.
ASSERT(static_cast<int>(offset) == offset);
return static_cast<int>(offset);
}
void MacroAssembler::PushHandleScope(Register scratch) {
ExternalReference extensions_address =
ExternalReference::handle_scope_extensions_address();
const int kExtensionsOffset = 0;
const int kNextOffset = Offset(
ExternalReference::handle_scope_next_address(),
extensions_address);
const int kLimitOffset = Offset(
ExternalReference::handle_scope_limit_address(),
extensions_address);
// Push the number of extensions, smi-tagged so the gc will ignore it.
movq(kScratchRegister, extensions_address);
movq(scratch, Operand(kScratchRegister, kExtensionsOffset));
movq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
Integer32ToSmi(scratch, scratch);
push(scratch);
// Push next and limit pointers which will be wordsize aligned and
// hence automatically smi tagged.
push(Operand(kScratchRegister, kNextOffset));
push(Operand(kScratchRegister, kLimitOffset));
}
Object* MacroAssembler::PopHandleScopeHelper(Register saved,
Register scratch,
bool gc_allowed) {
ExternalReference extensions_address =
ExternalReference::handle_scope_extensions_address();
const int kExtensionsOffset = 0;
const int kNextOffset = Offset(
ExternalReference::handle_scope_next_address(),
extensions_address);
const int kLimitOffset = Offset(
ExternalReference::handle_scope_limit_address(),
extensions_address);
Object* result = NULL;
Label write_back;
movq(kScratchRegister, extensions_address);
cmpq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
j(equal, &write_back);
push(saved);
if (gc_allowed) {
CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
} else {
result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
if (result->IsFailure()) return result;
}
pop(saved);
movq(kScratchRegister, extensions_address);
bind(&write_back);
pop(Operand(kScratchRegister, kLimitOffset));
pop(Operand(kScratchRegister, kNextOffset));
pop(scratch);
SmiToInteger32(scratch, scratch);
movq(Operand(kScratchRegister, kExtensionsOffset), scratch);
return result;
}
void MacroAssembler::PopHandleScope(Register saved, Register scratch) {
PopHandleScopeHelper(saved, scratch, true);
}
Object* MacroAssembler::TryPopHandleScope(Register saved, Register scratch) {
return PopHandleScopeHelper(saved, scratch, false);
}
void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
int result_size) {
// Set the entry point and jump to the C entry runtime stub.
@ -2208,7 +2335,8 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
}
void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
void MacroAssembler::EnterExitFramePrologue(ExitFrame::Mode mode,
bool save_rax) {
// Setup the frame structure on the stack.
// All constants are relative to the frame pointer of the exit frame.
ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
@ -2226,18 +2354,19 @@ void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
// Save the frame pointer and the context in top.
ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
ExternalReference context_address(Top::k_context_address);
movq(r14, rax); // Backup rax before we use it.
if (save_rax) {
movq(r14, rax); // Backup rax before we use it.
}
movq(rax, rbp);
store_rax(c_entry_fp_address);
movq(rax, rsi);
store_rax(context_address);
}
// Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
// so it must be retained across the C-call.
int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
lea(r12, Operand(rbp, r14, times_pointer_size, offset));
void MacroAssembler::EnterExitFrameEpilogue(ExitFrame::Mode mode,
int result_size,
int argc) {
#ifdef ENABLE_DEBUGGER_SUPPORT
// Save the state of all registers to the stack from the memory
// location. This is needed to allow nested break points.
@ -2258,7 +2387,7 @@ void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
// Reserve space for the Arguments object. The Windows 64-bit ABI
// requires us to pass this structure as a pointer to its location on
// the stack. The structure contains 2 values.
int argument_stack_space = 2 * kPointerSize;
int argument_stack_space = argc * kPointerSize;
// We also need backing space for 4 parameters, even though
// we only pass one or two parameter, and it is in a register.
int argument_mirror_space = 4 * kPointerSize;
@ -2280,6 +2409,33 @@ void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
}
void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
EnterExitFramePrologue(mode, true);
// Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
// so it must be retained across the C-call.
int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
lea(r12, Operand(rbp, r14, times_pointer_size, offset));
EnterExitFrameEpilogue(mode, result_size, 2);
}
void MacroAssembler::EnterApiExitFrame(ExitFrame::Mode mode,
int stack_space,
int argc,
int result_size) {
EnterExitFramePrologue(mode, false);
// Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
// so it must be retained across the C-call.
int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
lea(r12, Operand(rbp, (stack_space * kPointerSize) + offset));
EnterExitFrameEpilogue(mode, result_size, argc);
}
void MacroAssembler::LeaveExitFrame(ExitFrame::Mode mode, int result_size) {
// Registers:
// r12 : argv

43
deps/v8/src/x64/macro-assembler-x64.h

@ -163,6 +163,11 @@ class MacroAssembler: public Assembler {
// to the first argument in register rsi.
void EnterExitFrame(ExitFrame::Mode mode, int result_size = 1);
void EnterApiExitFrame(ExitFrame::Mode mode,
int stack_space,
int argc,
int result_size = 1);
// Leave the current exit frame. Expects/provides the return value in
// register rax:rdx (untouched) and the pointer to the first
// argument in register rsi.
@ -719,18 +724,36 @@ class MacroAssembler: public Assembler {
// Call a code stub.
void CallStub(CodeStub* stub);
// Call a code stub and return the code object called. Try to generate
// the code if necessary. Do not perform a GC but instead return a retry
// after GC failure.
Object* TryCallStub(CodeStub* stub);
// Tail call a code stub (jump).
void TailCallStub(CodeStub* stub);
// Tail call a code stub (jump) and return the code object called. Try to
// generate the code if necessary. Do not perform a GC but instead return
// a retry after GC failure.
Object* TryTailCallStub(CodeStub* stub);
// Return from a code stub after popping its arguments.
void StubReturn(int argc);
// Call a runtime routine.
void CallRuntime(Runtime::Function* f, int num_arguments);
// Call a runtime function, returning the CodeStub object called.
// Try to generate the stub code if necessary. Do not perform a GC
// but instead return a retry after GC failure.
Object* TryCallRuntime(Runtime::Function* f, int num_arguments);
// Convenience function: Same as above, but takes the fid instead.
void CallRuntime(Runtime::FunctionId id, int num_arguments);
// Convenience function: Same as above, but takes the fid instead.
Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
// Convenience function: call an external reference.
void CallExternalReference(const ExternalReference& ext,
int num_arguments);
@ -747,6 +770,16 @@ class MacroAssembler: public Assembler {
int num_arguments,
int result_size);
void PushHandleScope(Register scratch);
// Pops a handle scope using the specified scratch register and
// ensuring that saved register is left unchanged.
void PopHandleScope(Register saved, Register scratch);
// As PopHandleScope, but does not perform a GC. Instead, returns a
// retry after GC failure object if GC is necessary.
Object* TryPopHandleScope(Register saved, Register scratch);
// Jump to a runtime routine.
void JumpToExternalReference(const ExternalReference& ext, int result_size);
@ -835,6 +868,9 @@ class MacroAssembler: public Assembler {
void EnterFrame(StackFrame::Type type);
void LeaveFrame(StackFrame::Type type);
void EnterExitFramePrologue(ExitFrame::Mode mode, bool save_rax);
void EnterExitFrameEpilogue(ExitFrame::Mode mode, int result_size, int argc);
// Allocation support helpers.
// Loads the top of new-space into the result register.
// If flags contains RESULT_CONTAINS_TOP then result_end is valid and
@ -848,6 +884,13 @@ class MacroAssembler: public Assembler {
// Update allocation top with value in result_end register.
// If scratch is valid, it contains the address of the allocation top.
void UpdateAllocationTopHelper(Register result_end, Register scratch);
// Helper for PopHandleScope. Allowed to perform a GC and returns
// NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
// possibly returns a failure object indicating an allocation failure.
Object* PopHandleScopeHelper(Register saved,
Register scratch,
bool gc_allowed);
};

81
deps/v8/src/x64/stub-cache-x64.cc

@ -2211,23 +2211,80 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object,
// Check that the maps haven't changed.
Register reg =
CheckPrototypes(object, receiver, holder,
scratch1, scratch2, scratch3, name, miss);
CheckPrototypes(object, receiver, holder, scratch1,
scratch2, scratch3, name, miss);
// Push the arguments on the JS stack of the caller.
__ pop(scratch2); // remove return address
Handle<AccessorInfo> callback_handle(callback);
__ EnterInternalFrame();
__ PushHandleScope(scratch2);
// Push the stack address where the list of arguments ends.
__ movq(scratch2, rsp);
__ subq(scratch2, Immediate(2 * kPointerSize));
__ push(scratch2);
__ push(receiver); // receiver
__ push(reg); // holder
__ Move(reg, Handle<AccessorInfo>(callback)); // callback data
__ push(reg);
__ push(FieldOperand(reg, AccessorInfo::kDataOffset));
if (Heap::InNewSpace(callback_handle->data())) {
__ Move(scratch2, callback_handle);
__ push(FieldOperand(scratch2, AccessorInfo::kDataOffset)); // data
} else {
__ Push(Handle<Object>(callback_handle->data()));
}
__ push(name_reg); // name
__ push(scratch2); // restore return address
// Save a pointer to where we pushed the arguments pointer.
// This will be passed as the const AccessorInfo& to the C++ callback.
#ifdef _WIN64
// Win64 uses first register--rcx--for returned value.
Register accessor_info_arg = r8;
Register name_arg = rdx;
#else
Register accessor_info_arg = rdx; // temporary, copied to rsi by the stub.
Register name_arg = rdi;
#endif
// Do tail-call to the runtime system.
ExternalReference load_callback_property =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
__ TailCallExternalReference(load_callback_property, 5, 1);
__ movq(accessor_info_arg, rsp);
__ addq(accessor_info_arg, Immediate(4 * kPointerSize));
__ movq(name_arg, rsp);
// Do call through the api.
ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace);
Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address);
ApiGetterEntryStub stub(callback_handle, &fun);
#ifdef _WIN64
// We need to prepare a slot for result handle on stack and put
// a pointer to it into 1st arg register.
__ push(Immediate(0));
__ movq(rcx, rsp);
#endif
// Emitting a stub call may try to allocate (if the code is not
// already generated). Do not allow the assembler to perform a
// garbage collection but instead return the allocation failure
// object.
Object* result = masm()->TryCallStub(&stub);
if (result->IsFailure()) {
*failure = Failure::cast(result);
return false;
}
#ifdef _WIN64
// Discard allocated slot.
__ addq(rsp, Immediate(kPointerSize));
#endif
// We need to avoid using rax since that now holds the result.
Register tmp = scratch2.is(rax) ? reg : scratch2;
// Emitting PopHandleScope may try to allocate. Do not allow the
// assembler to perform a garbage collection but instead return a
// failure object.
result = masm()->TryPopHandleScope(rax, tmp);
if (result->IsFailure()) {
*failure = Failure::cast(result);
return false;
}
__ LeaveInternalFrame();
__ ret(0);
return true;
}

4
deps/v8/test/cctest/test-debug.cc

@ -1175,11 +1175,11 @@ TEST(BreakPointReturn) {
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
CHECK_EQ(0, last_source_line);
CHECK_EQ(16, last_source_column);
CHECK_EQ(15, last_source_column);
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
CHECK_EQ(0, last_source_line);
CHECK_EQ(16, last_source_column);
CHECK_EQ(15, last_source_column);
// Run without breakpoints.
ClearBreakPoint(bp);

57
deps/v8/test/cctest/test-regexp.cc

@ -1399,7 +1399,8 @@ TEST(LatinCanonicalize) {
for (uc32 c = 128; c < (1 << 21); c++)
CHECK_GE(canonicalize(c), 128);
unibrow::Mapping<unibrow::ToUppercase> to_upper;
for (uc32 c = 0; c < (1 << 21); c++) {
// Canonicalization is only defined for the Basic Multilingual Plane.
for (uc32 c = 0; c < (1 << 16); c++) {
unibrow::uchar upper[unibrow::ToUppercase::kMaxWidth];
int length = to_upper.get(c, '\0', upper);
if (length == 0) {
@ -1414,7 +1415,7 @@ TEST(LatinCanonicalize) {
}
static uc32 CanonRange(uc32 c) {
static uc32 CanonRangeEnd(uc32 c) {
unibrow::uchar canon[unibrow::CanonicalizationRange::kMaxWidth];
int count = unibrow::CanonicalizationRange::Convert(c, '\0', canon, NULL);
if (count == 0) {
@ -1427,47 +1428,29 @@ static uc32 CanonRange(uc32 c) {
TEST(RangeCanonicalization) {
CHECK_NE(CanonRange(0) & CharacterRange::kStartMarker, 0);
// Check that we arrive at the same result when using the basic
// range canonicalization primitives as when using immediate
// canonicalization.
unibrow::Mapping<unibrow::Ecma262UnCanonicalize> un_canonicalize;
for (int i = 0; i < CharacterRange::kRangeCanonicalizeMax; i++) {
int range = CanonRange(i);
int indirect_length = 0;
unibrow::uchar indirect[unibrow::Ecma262UnCanonicalize::kMaxWidth];
if ((range & CharacterRange::kStartMarker) == 0) {
indirect_length = un_canonicalize.get(i - range, '\0', indirect);
for (int i = 0; i < indirect_length; i++)
indirect[i] += range;
} else {
indirect_length = un_canonicalize.get(i, '\0', indirect);
}
unibrow::uchar direct[unibrow::Ecma262UnCanonicalize::kMaxWidth];
int direct_length = un_canonicalize.get(i, '\0', direct);
CHECK_EQ(direct_length, indirect_length);
}
// Check that we arrive at the same results when skipping over
// canonicalization ranges.
int next_block = 0;
while (next_block < CharacterRange::kRangeCanonicalizeMax) {
uc32 start = CanonRange(next_block);
CHECK_NE((start & CharacterRange::kStartMarker), 0);
unsigned dist = start & CharacterRange::kPayloadMask;
unibrow::uchar first[unibrow::Ecma262UnCanonicalize::kMaxWidth];
int first_length = un_canonicalize.get(next_block, '\0', first);
for (unsigned i = 1; i < dist; i++) {
CHECK_EQ(i, CanonRange(next_block + i));
unibrow::uchar succ[unibrow::Ecma262UnCanonicalize::kMaxWidth];
int succ_length = un_canonicalize.get(next_block + i, '\0', succ);
CHECK_EQ(first_length, succ_length);
for (int j = 0; j < succ_length; j++) {
int calc = first[j] + i;
int found = succ[j];
CHECK_EQ(calc, found);
int block_start = 0;
while (block_start <= 0xFFFF) {
uc32 block_end = CanonRangeEnd(block_start);
unsigned block_length = block_end - block_start + 1;
if (block_length > 1) {
unibrow::uchar first[unibrow::Ecma262UnCanonicalize::kMaxWidth];
int first_length = un_canonicalize.get(block_start, '\0', first);
for (unsigned i = 1; i < block_length; i++) {
unibrow::uchar succ[unibrow::Ecma262UnCanonicalize::kMaxWidth];
int succ_length = un_canonicalize.get(block_start + i, '\0', succ);
CHECK_EQ(first_length, succ_length);
for (int j = 0; j < succ_length; j++) {
int calc = first[j] + i;
int found = succ[j];
CHECK_EQ(calc, found);
}
}
}
next_block = next_block + dist;
block_start = block_start + block_length;
}
}

14
deps/v8/test/mjsunit/debug-breakpoints.js

@ -43,12 +43,12 @@ bp1 = Debug.setBreakPoint(f, 0, 8);
assertEquals("() {a=1;[B0]b=2}", Debug.showBreakPoints(f));
bp2 = Debug.setBreakPoint(f, 0, 4);
assertEquals("() {[B0]a=1;[B1]b=2}", Debug.showBreakPoints(f));
bp3 = Debug.setBreakPoint(f, 0, 12);
assertEquals("() {[B0]a=1;[B1]b=2}[B2]", Debug.showBreakPoints(f));
bp3 = Debug.setBreakPoint(f, 0, 11);
assertEquals("() {[B0]a=1;[B1]b=2[B2]}", Debug.showBreakPoints(f));
Debug.clearBreakPoint(bp1);
assertEquals("() {[B0]a=1;b=2}[B1]", Debug.showBreakPoints(f));
assertEquals("() {[B0]a=1;b=2[B1]}", Debug.showBreakPoints(f));
Debug.clearBreakPoint(bp2);
assertEquals("() {a=1;b=2}[B0]", Debug.showBreakPoints(f));
assertEquals("() {a=1;b=2[B0]}", Debug.showBreakPoints(f));
Debug.clearBreakPoint(bp3);
assertEquals("() {a=1;b=2}", Debug.showBreakPoints(f));
@ -96,21 +96,21 @@ bp3 = Debug.setBreakPoint(g, 3, 0);
// }[B2]
assertTrue(Debug.showBreakPoints(g).indexOf("[B0]a=1;") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("[B1]b=2;") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("}[B2]") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("[B2]}") > 0);
Debug.clearBreakPoint(bp1);
// function g() {
// [B0]a=1;
// b=2;
// }[B1]
assertTrue(Debug.showBreakPoints(g).indexOf("[B0]a=1;") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("}[B1]") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("[B1]}") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("[B2]") < 0);
Debug.clearBreakPoint(bp2);
// function g() {
// a=1;
// b=2;
// }[B0]
assertTrue(Debug.showBreakPoints(g).indexOf("}[B0]") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("[B0]}") > 0);
assertTrue(Debug.showBreakPoints(g).indexOf("[B1]") < 0);
Debug.clearBreakPoint(bp3);
// function g() {

10
deps/v8/test/mjsunit/debug-conditional-breakpoints.js

@ -136,7 +136,7 @@ Debug.clearBreakPoint(bp);
// Conditional breakpoint which checks a local variable.
break_point_hit_count = 0;
bp = Debug.setBreakPoint(h, 0, 23, 'a % 2 == 0');
bp = Debug.setBreakPoint(h, 0, 22, 'a % 2 == 0');
for (var i = 0; i < 10; i++) {
g();
}
@ -146,8 +146,8 @@ Debug.clearBreakPoint(bp);
// Multiple conditional breakpoint which the same condition.
break_point_hit_count = 0;
bp1 = Debug.setBreakPoint(h, 0, 23, 'a % 2 == 0');
bp2 = Debug.setBreakPoint(h, 0, 23, 'a % 2 == 0');
bp1 = Debug.setBreakPoint(h, 0, 22, 'a % 2 == 0');
bp2 = Debug.setBreakPoint(h, 0, 22, 'a % 2 == 0');
for (var i = 0; i < 10; i++) {
g();
}
@ -159,8 +159,8 @@ Debug.clearBreakPoint(bp2);
// Multiple conditional breakpoint which different conditions.
break_point_hit_count = 0;
bp1 = Debug.setBreakPoint(h, 0, 23, 'a % 2 == 0');
bp2 = Debug.setBreakPoint(h, 0, 23, '(a + 1) % 2 == 0');
bp1 = Debug.setBreakPoint(h, 0, 22, 'a % 2 == 0');
bp2 = Debug.setBreakPoint(h, 0, 22, '(a + 1) % 2 == 0');
for (var i = 0; i < 10; i++) {
g();
}

15
deps/v8/test/mjsunit/debug-enable-disable-breakpoints.js

@ -88,3 +88,18 @@ assertEquals(5, break_point_hit_count);
Debug.disableBreakPoint(bp1);
f();
assertEquals(6, break_point_hit_count);
// Deactivate all breakpoints.
Debug.debuggerFlags().breakPointsActive.setValue(false);
f();
assertEquals(6, break_point_hit_count);
// Enable the first breakpoint.
Debug.enableBreakPoint(bp1);
f();
assertEquals(6, break_point_hit_count);
// Activate all breakpoints.
Debug.debuggerFlags().breakPointsActive.setValue(true);
f();
assertEquals(7, break_point_hit_count);

2
deps/v8/test/mjsunit/debug-return-value.js

@ -101,7 +101,7 @@ function listener(event, exec_state, event_data, data) {
exec_state.prepareStep(Debug.StepAction.StepIn, 1);
} else {
// Position at the end of the function.
assertEquals(debugger_source_position + 51,
assertEquals(debugger_source_position + 50,
exec_state.frame(0).sourcePosition());
// Just about to return from the function.

42
deps/v8/test/mjsunit/regress/regress-784.js

@ -0,0 +1,42 @@
// Copyright 2010 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.
// Test that CallApplyLazy, generating optimized code for apply calls of the
// form x.apply(y, arguments), does not leave an extra copy of the result
// on the stack.
// See http://code.google.com/p/v8/issues/detail?id=784
A = {x:{y:function(i){return i;}}};
B = function(x){return 17;};
foo = function () {
A.x.y(B.apply(this, arguments));
};
foo();
foo("Hello", "There");

51
deps/v8/test/mjsunit/regress/regress-806.js

@ -0,0 +1,51 @@
// Copyright 2010 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.
// Test that we do no use r12 as a receiver in inlined NamedStores on x64.
// See: http://code.google.com/p/v8/issues/detail?id=806
function foo(a) {
for (var o = 1; o < 2; o++) {
for (var n = 1; n < 2; n++) {
for (var m = 1; m < 2; m++) {
for (var l = 1; l < 2; l++) {
for (var i = 1; i < 2; i++) {
for (var j = 1; j < 2; j++) {
for (var k = 1; k < 2; k++) {
var z = a.foo;
z.foo = i * j * k * m * n * o;
}
}
}
}
}
}
}
}
foo({foo: {foo: 1}});

10
deps/v8/tools/presubmit.py

@ -27,8 +27,14 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
try:
import hashlib
md5er = hashlib.md5
except ImportError, e:
import md5
md5er = md5.new
import md5
import optparse
import os
from os.path import abspath, join, dirname, basename, exists
@ -126,7 +132,7 @@ class FileContentsCache(object):
for file in files:
try:
handle = open(file, "r")
file_sum = md5.new(handle.read()).digest()
file_sum = md5er(handle.read()).digest()
if not file in self.sums or self.sums[file] != file_sum:
changed_or_new.append(file)
self.sums[file] = file_sum

26
deps/v8/tools/v8.xcodeproj/project.pbxproj

@ -245,6 +245,10 @@
9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03E410BD412600F8BFBA /* fast-codegen-arm.cc */; };
9FC86ABD0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FC86ABB0F5FEDAC00F22668 /* oprofile-agent.cc */; };
9FC86ABE0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FC86ABB0F5FEDAC00F22668 /* oprofile-agent.cc */; };
C2BD4BD7120165460046BF9F /* dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD5120165460046BF9F /* dtoa.cc */; };
C2BD4BDB120165A70046BF9F /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */; };
C2BD4BE4120166180046BF9F /* fixed-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */; };
C2BD4BE51201661F0046BF9F /* dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = C2BD4BD5120165460046BF9F /* dtoa.cc */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -308,7 +312,6 @@
/* Begin PBXFileReference section */
22A76C900FF259E600FDC694 /* log-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "log-inl.h"; sourceTree = "<group>"; };
58242A1E0FA1F14D00BD6F59 /* json-delay.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "json-delay.js"; sourceTree = "<group>"; };
58950D4E0F55514900F3E8BA /* jump-target-light.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "jump-target-light.cc"; sourceTree = "<group>"; };
58950D4F0F55514900F3E8BA /* jump-target-heavy.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "jump-target-heavy.cc"; sourceTree = "<group>"; };
58950D500F55514900F3E8BA /* jump-target.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "jump-target.cc"; sourceTree = "<group>"; };
@ -528,12 +531,8 @@
897FF1A30E719B8F00D62E90 /* zone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zone.h; sourceTree = "<group>"; };
897FF1A60E719BC100D62E90 /* apinatives.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = apinatives.js; sourceTree = "<group>"; };
897FF1A70E719BC100D62E90 /* array.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = array.js; sourceTree = "<group>"; };
897FF1A80E719BC100D62E90 /* date-delay.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "date-delay.js"; sourceTree = "<group>"; };
897FF1A90E719BC100D62E90 /* debug-delay.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "debug-delay.js"; sourceTree = "<group>"; };
897FF1AA0E719BC100D62E90 /* math.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = math.js; sourceTree = "<group>"; };
897FF1AB0E719BC100D62E90 /* messages.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = messages.js; sourceTree = "<group>"; };
897FF1AC0E719BC100D62E90 /* mirror-delay.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "mirror-delay.js"; sourceTree = "<group>"; };
897FF1AD0E719BC100D62E90 /* regexp-delay.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "regexp-delay.js"; sourceTree = "<group>"; };
897FF1AE0E719BC100D62E90 /* runtime.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = runtime.js; sourceTree = "<group>"; };
897FF1AF0E719BC100D62E90 /* string.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = string.js; sourceTree = "<group>"; };
897FF1B00E719BC100D62E90 /* uri.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = uri.js; sourceTree = "<group>"; };
@ -629,6 +628,10 @@
9FC86ABC0F5FEDAC00F22668 /* oprofile-agent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "oprofile-agent.h"; sourceTree = "<group>"; };
9FF7A28211A642EA0051B8F2 /* unbound-queue-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unbound-queue-inl.h"; sourceTree = "<group>"; };
9FF7A28311A642EA0051B8F2 /* unbound-queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unbound-queue.h"; sourceTree = "<group>"; };
C2BD4BD5120165460046BF9F /* dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cc; sourceTree = "<group>"; };
C2BD4BD6120165460046BF9F /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; };
C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fixed-dtoa.cc"; sourceTree = "<group>"; };
C2BD4BDA120165A70046BF9F /* fixed-dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fixed-dtoa.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -734,6 +737,8 @@
897FF1020E719B8F00D62E90 /* assembler-ia32.h */,
897FF1030E719B8F00D62E90 /* assembler.cc */,
897FF1040E719B8F00D62E90 /* assembler.h */,
C2BD4BD9120165A70046BF9F /* fixed-dtoa.cc */,
C2BD4BDA120165A70046BF9F /* fixed-dtoa.h */,
897FF1050E719B8F00D62E90 /* ast.cc */,
897FF1060E719B8F00D62E90 /* ast.h */,
897FF1070E719B8F00D62E90 /* bootstrapper.cc */,
@ -801,6 +806,8 @@
9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */,
9FA38B9F1175B2D200C4CD55 /* diy-fp.h */,
9FA38BA01175B2D200C4CD55 /* double.h */,
C2BD4BD5120165460046BF9F /* dtoa.cc */,
C2BD4BD6120165460046BF9F /* dtoa.h */,
897FF12F0E719B8F00D62E90 /* dtoa-config.c */,
897FF1300E719B8F00D62E90 /* execution.cc */,
897FF1310E719B8F00D62E90 /* execution.h */,
@ -1017,13 +1024,8 @@
children = (
897FF1A60E719BC100D62E90 /* apinatives.js */,
897FF1A70E719BC100D62E90 /* array.js */,
897FF1A80E719BC100D62E90 /* date-delay.js */,
897FF1A90E719BC100D62E90 /* debug-delay.js */,
58242A1E0FA1F14D00BD6F59 /* json-delay.js */,
897FF1AA0E719BC100D62E90 /* math.js */,
897FF1AB0E719BC100D62E90 /* messages.js */,
897FF1AC0E719BC100D62E90 /* mirror-delay.js */,
897FF1AD0E719BC100D62E90 /* regexp-delay.js */,
897FF1AE0E719BC100D62E90 /* runtime.js */,
897FF1AF0E719BC100D62E90 /* string.js */,
897FF1B00E719BC100D62E90 /* uri.js */,
@ -1284,6 +1286,7 @@
89A88DF90E71A6430043BA31 /* compiler.cc in Sources */,
89A88DFA0E71A6440043BA31 /* contexts.cc in Sources */,
89A88DFB0E71A6440043BA31 /* conversions.cc in Sources */,
C2BD4BDB120165A70046BF9F /* fixed-dtoa.cc in Sources */,
89A88DFC0E71A6460043BA31 /* counters.cc in Sources */,
89A88DFD0E71A6470043BA31 /* cpu-ia32.cc in Sources */,
9F2B37271152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
@ -1291,6 +1294,7 @@
89A88DFE0E71A6480043BA31 /* dateparser.cc in Sources */,
8956B6CF0F5D86730033B5A2 /* debug-agent.cc in Sources */,
898BD20E0EF6CC930068B00A /* debug-ia32.cc in Sources */,
C2BD4BD7120165460046BF9F /* dtoa.cc in Sources */,
89A88DFF0E71A6530043BA31 /* debug.cc in Sources */,
89A88E000E71A6540043BA31 /* disasm-ia32.cc in Sources */,
89A88E010E71A6550043BA31 /* disassembler.cc in Sources */,
@ -1409,6 +1413,8 @@
89F23C4F0E78D5B2006B2466 /* counters.cc in Sources */,
89F23C9A0E78D5EC006B2466 /* cpu-arm.cc in Sources */,
9F2B37261152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
C2BD4BE4120166180046BF9F /* fixed-dtoa.cc in Sources */,
C2BD4BE51201661F0046BF9F /* dtoa.cc in Sources */,
9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */,
89F23C510E78D5B2006B2466 /* dateparser.cc in Sources */,
894599A30F5D8729008DA8FB /* debug-agent.cc in Sources */,

Loading…
Cancel
Save