diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2011-09-15 09:41:08 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-09-15 09:42:06 -0700 |
commit | 1b15af9dd2bf4adb7a2e73ae17a12e2e98a88f72 (patch) | |
tree | feede6d06b8c99b92e29a9fdcf0e9ade05b981d0 /deps/v8/src | |
parent | f8b90946aec53b453d82dd66a4d812ec86487629 (diff) | |
download | node-new-1b15af9dd2bf4adb7a2e73ae17a12e2e98a88f72.tar.gz |
Upgrade V8 to 3.6.4
Diffstat (limited to 'deps/v8/src')
170 files changed, 2834 insertions, 1959 deletions
diff --git a/deps/v8/src/accessors.cc b/deps/v8/src/accessors.cc index f02efa55a2..951209d964 100644 --- a/deps/v8/src/accessors.cc +++ b/deps/v8/src/accessors.cc @@ -710,6 +710,7 @@ class FrameFunctionIterator { } while (next_function != NULL); return false; } + private: void GetFunctions() { functions_.Rewind(0); diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 26558c4292..5c8a3142ae 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -3266,6 +3266,42 @@ bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) { namespace { +static i::ElementsKind GetElementsKindFromExternalArrayType( + ExternalArrayType array_type) { + switch (array_type) { + case kExternalByteArray: + return i::EXTERNAL_BYTE_ELEMENTS; + break; + case kExternalUnsignedByteArray: + return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS; + break; + case kExternalShortArray: + return i::EXTERNAL_SHORT_ELEMENTS; + break; + case kExternalUnsignedShortArray: + return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS; + break; + case kExternalIntArray: + return i::EXTERNAL_INT_ELEMENTS; + break; + case kExternalUnsignedIntArray: + return i::EXTERNAL_UNSIGNED_INT_ELEMENTS; + break; + case kExternalFloatArray: + return i::EXTERNAL_FLOAT_ELEMENTS; + break; + case kExternalDoubleArray: + return i::EXTERNAL_DOUBLE_ELEMENTS; + break; + case kExternalPixelArray: + return i::EXTERNAL_PIXEL_ELEMENTS; + break; + } + UNREACHABLE(); + return i::DICTIONARY_ELEMENTS; +} + + void PrepareExternalArrayElements(i::Handle<i::JSObject> object, void* data, ExternalArrayType array_type, @@ -3284,9 +3320,9 @@ void PrepareExternalArrayElements(i::Handle<i::JSObject> object, elements->map() != isolate->heap()->MapForExternalArrayType(array_type); if (cant_reuse_map) { i::Handle<i::Map> external_array_map = - isolate->factory()->GetExternalArrayElementsMap( + isolate->factory()->GetElementsTransitionMap( i::Handle<i::Map>(object->map()), - array_type, + GetElementsKindFromExternalArrayType(array_type), object->HasFastProperties()); object->set_map(*external_array_map); } @@ -3348,6 +3384,7 @@ int v8::Object::GetIndexedPropertiesPixelDataLength() { } } + void v8::Object::SetIndexedPropertiesToExternalArrayData( void* data, ExternalArrayType array_type, diff --git a/deps/v8/src/arguments.h b/deps/v8/src/arguments.h index 72bbe1dd1f..e9a32702cf 100644 --- a/deps/v8/src/arguments.h +++ b/deps/v8/src/arguments.h @@ -75,6 +75,7 @@ class Arguments BASE_EMBEDDED { int length() const { return length_; } Object** arguments() { return arguments_; } + private: int length_; Object** arguments_; diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc index a35380c175..60d2081c29 100644 --- a/deps/v8/src/arm/builtins-arm.cc +++ b/deps/v8/src/arm/builtins-arm.cc @@ -1230,16 +1230,17 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { // 2. Get the function to call (passed as receiver) from the stack, check // if it is a function. // r0: actual number of arguments - Label non_function; + Label slow, non_function; __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); __ JumpIfSmi(r1, &non_function); __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); - __ b(ne, &non_function); + __ b(ne, &slow); // 3a. Patch the first argument if necessary when calling a function. // r0: actual number of arguments // r1: function Label shift_arguments; + __ mov(r4, Operand(0, RelocInfo::NONE)); // indicate regular JS_FUNCTION { Label convert_to_object, use_global_receiver, patch_receiver; // Change context eagerly in case we need the global receiver. __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); @@ -1286,8 +1287,9 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ pop(r0); __ mov(r0, Operand(r0, ASR, kSmiTagSize)); __ LeaveInternalFrame(); - // Restore the function to r1. + // Restore the function to r1, and the flag to r4. __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); + __ mov(r4, Operand(0, RelocInfo::NONE)); __ jmp(&patch_receiver); // Use the global receiver object from the called function as the @@ -1307,23 +1309,30 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ jmp(&shift_arguments); } - // 3b. Patch the first argument when calling a non-function. The + // 3b. Check for function proxy. + __ bind(&slow); + __ mov(r4, Operand(1, RelocInfo::NONE)); // indicate function proxy + __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE)); + __ b(eq, &shift_arguments); + __ bind(&non_function); + __ mov(r4, Operand(2, RelocInfo::NONE)); // indicate non-function + + // 3c. Patch the first argument when calling a non-function. The // CALL_NON_FUNCTION builtin expects the non-function callee as // receiver, so overwrite the first argument which will ultimately // become the receiver. // r0: actual number of arguments // r1: function - __ bind(&non_function); + // r4: call type (0: JS function, 1: function proxy, 2: non-function) __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); __ str(r1, MemOperand(r2, -kPointerSize)); - // Clear r1 to indicate a non-function being called. - __ mov(r1, Operand(0, RelocInfo::NONE)); // 4. Shift arguments and return address one slot down on the stack // (overwriting the original receiver). Adjust argument count to make // the original first argument the new receiver. // r0: actual number of arguments // r1: function + // r4: call type (0: JS function, 1: function proxy, 2: non-function) __ bind(&shift_arguments); { Label loop; // Calculate the copy start address (destination). Copy end address is sp. @@ -1341,16 +1350,28 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ pop(); } - // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. + // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, + // or a function proxy via CALL_FUNCTION_PROXY. // r0: actual number of arguments // r1: function - { Label function; - __ tst(r1, r1); - __ b(ne, &function); + // r4: call type (0: JS function, 1: function proxy, 2: non-function) + { Label function, non_proxy; + __ tst(r4, r4); + __ b(eq, &function); // Expected number of arguments is 0 for CALL_NON_FUNCTION. __ mov(r2, Operand(0, RelocInfo::NONE)); - __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); __ SetCallKind(r5, CALL_AS_METHOD); + __ cmp(r4, Operand(1)); + __ b(ne, &non_proxy); + + __ push(r1); // re-add proxy object as additional argument + __ add(r0, r0, Operand(1)); + __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); + __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), + RelocInfo::CODE_TARGET); + + __ bind(&non_proxy); + __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), RelocInfo::CODE_TARGET); __ bind(&function); @@ -1393,7 +1414,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ push(r0); __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); - // Check the stack for overflow. We are not trying need to catch + // Check the stack for overflow. We are not trying to catch // interruptions (e.g. debug break and preemption) here, so the "real stack // limit" is checked. Label okay; @@ -1418,18 +1439,24 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ mov(r1, Operand(0, RelocInfo::NONE)); // initial index __ push(r1); + // Get the receiver. + __ ldr(r0, MemOperand(fp, kRecvOffset)); + + // Check that the function is a JS function (otherwise it must be a proxy). + Label push_receiver; + __ ldr(r1, MemOperand(fp, kFunctionOffset)); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); + __ b(ne, &push_receiver); + // Change context eagerly to get the right global object if necessary. - __ ldr(r0, MemOperand(fp, kFunctionOffset)); - __ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); - // Load the shared function info while the function is still in r0. - __ ldr(r1, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); + __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); + // Load the shared function info while the function is still in r1. + __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); // Compute the receiver. - Label call_to_object, use_global_receiver, push_receiver; - __ ldr(r0, MemOperand(fp, kRecvOffset)); - // Do not transform the receiver for strict mode functions. - __ ldr(r2, FieldMemOperand(r1, SharedFunctionInfo::kCompilerHintsOffset)); + Label call_to_object, use_global_receiver; + __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset)); __ tst(r2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize))); __ b(ne, &push_receiver); @@ -1504,9 +1531,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ b(ne, &loop); // Invoke the function. + Label call_proxy; ParameterCount actual(r0); __ mov(r0, Operand(r0, ASR, kSmiTagSize)); __ ldr(r1, MemOperand(fp, kFunctionOffset)); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); + __ b(ne, &call_proxy); __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); @@ -1514,6 +1544,20 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ LeaveInternalFrame(); __ add(sp, sp, Operand(3 * kPointerSize)); __ Jump(lr); + + // Invoke the function proxy. + __ bind(&call_proxy); + __ push(r1); // add function proxy as last argument + __ add(r0, r0, Operand(1)); + __ mov(r2, Operand(0, RelocInfo::NONE)); + __ SetCallKind(r5, CALL_AS_METHOD); + __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); + __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), + RelocInfo::CODE_TARGET); + + __ LeaveInternalFrame(); + __ add(sp, sp, Operand(3 * kPointerSize)); + __ Jump(lr); } diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index c310da88bc..e65f6d9b69 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -3432,7 +3432,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, // Retrieve the pending exception and clear the variable. __ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate))); __ ldr(r3, MemOperand(ip)); - __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate))); __ ldr(r0, MemOperand(ip)); __ str(r3, MemOperand(ip)); @@ -3567,7 +3567,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { __ mov(r7, Operand(Smi::FromInt(marker))); __ mov(r6, Operand(Smi::FromInt(marker))); __ mov(r5, - Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); + Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate))); __ ldr(r5, MemOperand(r5)); __ Push(r8, r7, r6, r5); @@ -3576,7 +3576,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // If this is the outermost JS call, set js_entry_sp value. Label non_outermost_js; - ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); + ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate); __ mov(r5, Operand(ExternalReference(js_entry_sp))); __ ldr(r6, MemOperand(r5)); __ cmp(r6, Operand::Zero()); @@ -3597,7 +3597,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // exception field in the JSEnv and return a failure sentinel. // Coming in here the fp will be invalid because the PushTryHandler below // sets it to 0 to signal the existence of the JSEntry frame. - __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate))); __ str(r0, MemOperand(ip)); __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); @@ -3615,7 +3615,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Clear any pending exceptions. __ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate))); __ ldr(r5, MemOperand(ip)); - __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate))); __ str(r5, MemOperand(ip)); @@ -3662,7 +3662,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Restore the top frame descriptors from the stack. __ pop(r3); __ mov(ip, - Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); + Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate))); __ str(r3, MemOperand(ip)); // Reset the stack to the callee saved registers. @@ -4534,7 +4534,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { // TODO(592): Rerunning the RegExp to get the stack overflow exception. __ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate))); __ ldr(r1, MemOperand(r1, 0)); - __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate))); __ ldr(r0, MemOperand(r2, 0)); __ cmp(r0, r1); @@ -4713,7 +4713,7 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) { void CallFunctionStub::Generate(MacroAssembler* masm) { - Label slow; + Label slow, non_function; // The receiver might implicitly be the global object. This is // indicated by passing the hole as the receiver to the call @@ -4739,7 +4739,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Check that the function is really a JavaScript function. // r1: pushed function (to be verified) - __ JumpIfSmi(r1, &slow); + __ JumpIfSmi(r1, &non_function); // Get the map of the function object. __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ b(ne, &slow); @@ -4767,8 +4767,23 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); + // Check for function proxy. + __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE)); + __ b(ne, &non_function); + __ push(r1); // put proxy as additional argument + __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE)); + __ mov(r2, Operand(0, RelocInfo::NONE)); + __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); + __ SetCallKind(r5, CALL_AS_FUNCTION); + { + Handle<Code> adaptor = + masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); + __ Jump(adaptor, RelocInfo::CODE_TARGET); + } + // CALL_NON_FUNCTION expects the non-function callee as receiver (instead // of the original receiver from the call site). + __ bind(&non_function); __ str(r1, MemOperand(sp, argc_ * kPointerSize)); __ mov(r0, Operand(argc_)); // Setup the number of arguments. __ mov(r2, Operand(0, RelocInfo::NONE)); diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc index 4d27a8d3ca..50ed8b1da7 100644 --- a/deps/v8/src/arm/full-codegen-arm.cc +++ b/deps/v8/src/arm/full-codegen-arm.cc @@ -2028,9 +2028,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr, // Record source position for debugger. SetSourcePosition(expr->position()); // Call the IC initialization code. - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ Call(ic, mode, expr->id()); RecordJSReturnSite(expr); // Restore context register. @@ -2061,9 +2060,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, // Record source position for debugger. SetSourcePosition(expr->position()); // Call the IC initialization code. - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic = - isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); + isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); RecordJSReturnSite(expr); @@ -2084,8 +2082,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, flags); + CallFunctionStub stub(arg_count, flags); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -2184,8 +2181,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); + CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -2514,7 +2510,7 @@ void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { &if_true, &if_false, &fall_through); __ JumpIfSmi(r0, if_false); - __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); + __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE); PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); Split(eq, if_true, if_false, fall_through); @@ -3553,9 +3549,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { __ mov(r2, Operand(expr->name())); RelocInfo::Mode mode = RelocInfo::CODE_TARGET; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arg_count, - NOT_IN_LOOP, - mode); + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ Call(ic, mode, expr->id()); // Restore context register. __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); diff --git a/deps/v8/src/arm/ic-arm.cc b/deps/v8/src/arm/ic-arm.cc index 6bad5ac03e..2e49cae928 100644 --- a/deps/v8/src/arm/ic-arm.cc +++ b/deps/v8/src/arm/ic-arm.cc @@ -146,7 +146,7 @@ static void GenerateDictionaryLoad(MacroAssembler* masm, StringDictionary::kElementsStartIndex * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ tst(scratch1, Operand(PropertyDetails::TypeField::mask() << kSmiTagSize)); + __ tst(scratch1, Operand(PropertyDetails::TypeField::kMask << kSmiTagSize)); __ b(ne, miss); // Get the value at the masked, scaled index and return. @@ -194,9 +194,9 @@ static void GenerateDictionaryStore(MacroAssembler* masm, const int kElementsStartOffset = StringDictionary::kHeaderSize + StringDictionary::kElementsStartIndex * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask - = (PropertyDetails::TypeField::mask() | - PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; + const int kTypeAndReadOnlyMask = + (PropertyDetails::TypeField::kMask | + PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); __ tst(scratch1, Operand(kTypeAndReadOnlyMask)); __ b(ne, miss); @@ -393,7 +393,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, // Probe the stub cache. Code::Flags flags = Code::ComputeFlags(kind, - NOT_IN_LOOP, MONOMORPHIC, extra_ic_state, NORMAL, @@ -734,9 +733,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // ----------------------------------- // Probe the stub cache. - Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, - NOT_IN_LOOP, - MONOMORPHIC); + Code::Flags flags = + Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC); Isolate::Current()->stub_cache()->GenerateProbe( masm, flags, r0, r2, r3, r4, r5); @@ -1380,10 +1378,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm, // ----------------------------------- // Get the receiver from the stack and probe the stub cache. - Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, - NOT_IN_LOOP, - MONOMORPHIC, - strict_mode); + Code::Flags flags = + Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode); Isolate::Current()->stub_cache()->GenerateProbe( masm, flags, r1, r2, r3, r4, r5); diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc index 30d7a1c2cd..30ccd05bee 100644 --- a/deps/v8/src/arm/lithium-arm.cc +++ b/deps/v8/src/arm/lithium-arm.cc @@ -311,13 +311,13 @@ void LCallKeyed::PrintDataTo(StringStream* stream) { void LCallNamed::PrintDataTo(StringStream* stream) { - SmartPointer<char> name_string = name()->ToCString(); + SmartArrayPointer<char> name_string = name()->ToCString(); stream->Add("%s #%d / ", *name_string, arity()); } void LCallGlobal::PrintDataTo(StringStream* stream) { - SmartPointer<char> name_string = name()->ToCString(); + SmartArrayPointer<char> name_string = name()->ToCString(); stream->Add("%s #%d / ", *name_string, arity()); } @@ -546,7 +546,8 @@ LChunk* LChunkBuilder::Build() { void LChunkBuilder::Abort(const char* format, ...) { if (FLAG_trace_bailout) { - SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + SmartArrayPointer<char> name( + info()->shared_info()->DebugName()->ToCString()); PrintF("Aborting LChunk building in @\"%s\": ", *name); va_list arguments; va_start(arguments, format); @@ -1860,15 +1861,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( HLoadKeyedSpecializedArrayElement* instr) { - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); Representation representation(instr->representation()); ASSERT( (representation.IsInteger32() && - (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (representation.IsDouble() && - ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); + ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); @@ -1877,7 +1878,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* load_instr = DefineAsRegister(result); // An unsigned int array load might overflow and cause a deopt, make sure it // has an environment. - return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ? + return (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) ? AssignEnvironment(load_instr) : load_instr; } @@ -1928,21 +1929,21 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( HStoreKeyedSpecializedArrayElement* instr) { Representation representation(instr->value()->representation()); - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); ASSERT( (representation.IsInteger32() && - (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (representation.IsDouble() && - ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); + ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); bool val_is_temp_register = - elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS || - elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS; + elements_kind == EXTERNAL_PIXEL_ELEMENTS || + elements_kind == EXTERNAL_FLOAT_ELEMENTS; LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) : UseRegister(instr->value()); diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h index 3632c8cf48..8c18760fd1 100644 --- a/deps/v8/src/arm/lithium-arm.h +++ b/deps/v8/src/arm/lithium-arm.h @@ -1158,7 +1158,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } - JSObject::ElementsKind elements_kind() const { + ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } }; @@ -1662,7 +1662,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - JSObject::ElementsKind elements_kind() const { + ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } }; diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc index 24e51e0681..f5d7449149 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.cc +++ b/deps/v8/src/arm/lithium-codegen-arm.cc @@ -101,7 +101,8 @@ void LCodeGen::FinishCode(Handle<Code> code) { void LCodeGen::Abort(const char* format, ...) { if (FLAG_trace_bailout) { - SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + SmartArrayPointer<char> name( + info()->shared_info()->DebugName()->ToCString()); PrintF("Aborting LCodeGen in @\"%s\": ", *name); va_list arguments; va_start(arguments, format); @@ -2410,11 +2411,11 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) { __ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); __ ubfx(scratch, scratch, Map::kElementsKindShift, Map::kElementsKindBitCount); - __ cmp(scratch, Operand(JSObject::FAST_ELEMENTS)); + __ cmp(scratch, Operand(FAST_ELEMENTS)); __ b(eq, &done); - __ cmp(scratch, Operand(JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); + __ cmp(scratch, Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); __ b(lt, &fail); - __ cmp(scratch, Operand(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); + __ cmp(scratch, Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); __ b(le, &done); __ bind(&fail); __ Abort("Check for fast or external elements failed."); @@ -2478,7 +2479,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( Register scratch = scratch0(); int shift_size = - ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS); + ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); int constant_key = 0; if (key_is_constant) { constant_key = ToInteger32(LConstantOperand::cast(instr->key())); @@ -2515,7 +2516,7 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( LLoadKeyedSpecializedArrayElement* instr) { Register external_pointer = ToRegister(instr->external_pointer()); Register key = no_reg; - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); bool key_is_constant = instr->key()->IsConstantOperand(); int constant_key = 0; if (key_is_constant) { @@ -2528,18 +2529,18 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( } int shift_size = ElementsKindToShiftSize(elements_kind); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || - elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || + elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { CpuFeatures::Scope scope(VFP3); DwVfpRegister result = ToDoubleRegister(instr->result()); Operand operand = key_is_constant ? Operand(constant_key * (1 << shift_size)) : Operand(key, LSL, shift_size); __ add(scratch0(), external_pointer, operand); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ vldr(result.low(), scratch0(), 0); __ vcvt_f64_f32(result, result.low()); - } else { // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS + } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS __ vldr(result, scratch0(), 0); } } else { @@ -2548,23 +2549,23 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( ? MemOperand(external_pointer, constant_key * (1 << shift_size)) : MemOperand(external_pointer, key, LSL, shift_size)); switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ ldrsb(result, mem_operand); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ ldrb(result, mem_operand); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: __ ldrsh(result, mem_operand); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ ldrh(result, mem_operand); break; - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: __ ldr(result, mem_operand); break; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ ldr(result, mem_operand); __ cmp(result, Operand(0x80000000)); // TODO(danno): we could be more clever here, perhaps having a special @@ -2572,12 +2573,12 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( // happens, and generate code that returns a double rather than int. DeoptimizeIf(cs, instr->environment()); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3177,7 +3178,7 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) { int arity = instr->arity(); Handle<Code> ic = - isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); + isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); CallCode(ic, RelocInfo::CODE_TARGET, instr); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); } @@ -3189,7 +3190,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { int arity = instr->arity(); RelocInfo::Mode mode = RelocInfo::CODE_TARGET; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); + isolate()->stub_cache()->ComputeCallInitialize(arity, mode); __ mov(r2, Operand(instr->name())); CallCode(ic, mode, instr); // Restore context register. @@ -3201,7 +3202,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { ASSERT(ToRegister(instr->result()).is(r0)); int arity = instr->arity(); - CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); + CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); __ Drop(1); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); @@ -3214,7 +3215,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { int arity = instr->arity(); RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); + isolate()->stub_cache()->ComputeCallInitialize(arity, mode); __ mov(r2, Operand(instr->name())); CallCode(ic, mode, instr); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); @@ -3340,7 +3341,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( } else { key = ToRegister(instr->key()); } - int shift_size = ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS); + int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); Operand operand = key_is_constant ? Operand(constant_key * (1 << shift_size) + FixedDoubleArray::kHeaderSize - kHeapObjectTag) @@ -3367,7 +3368,7 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( Register external_pointer = ToRegister(instr->external_pointer()); Register key = no_reg; - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); bool key_is_constant = instr->key()->IsConstantOperand(); int constant_key = 0; if (key_is_constant) { @@ -3380,17 +3381,17 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( } int shift_size = ElementsKindToShiftSize(elements_kind); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || - elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || + elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { CpuFeatures::Scope scope(VFP3); DwVfpRegister value(ToDoubleRegister(instr->value())); Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) : Operand(key, LSL, shift_size)); __ add(scratch0(), external_pointer, operand); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ vcvt_f32_f64(double_scratch0().low(), value); __ vstr(double_scratch0().low(), scratch0(), 0); - } else { // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS + } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS __ vstr(value, scratch0(), 0); } } else { @@ -3399,25 +3400,25 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( ? MemOperand(external_pointer, constant_key * (1 << shift_size)) : MemOperand(external_pointer, key, LSL, shift_size)); switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(value, mem_operand); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(value, mem_operand); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(value, mem_operand); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } diff --git a/deps/v8/src/arm/lithium-gap-resolver-arm.h b/deps/v8/src/arm/lithium-gap-resolver-arm.h index 334d2920b6..9dd09c8d03 100644 --- a/deps/v8/src/arm/lithium-gap-resolver-arm.h +++ b/deps/v8/src/arm/lithium-gap-resolver-arm.h @@ -40,7 +40,6 @@ class LGapResolver; class LGapResolver BASE_EMBEDDED { public: - explicit LGapResolver(LCodeGen* owner); // Resolve a set of parallel moves, emitting assembler instructions. diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index 613a1f69f1..f37f310218 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -760,9 +760,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); // Save the frame pointer and the context in top. - mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); + mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); str(fp, MemOperand(ip)); - mov(ip, Operand(ExternalReference(Isolate::k_context_address, isolate()))); + mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); str(cp, MemOperand(ip)); // Optionally save all double registers. @@ -838,11 +838,11 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, // Clear top frame. mov(r3, Operand(0, RelocInfo::NONE)); - mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); + mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); str(r3, MemOperand(ip)); // Restore current context from top and clear it in debug mode. - mov(ip, Operand(ExternalReference(Isolate::k_context_address, isolate()))); + mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); ldr(cp, MemOperand(ip)); #ifdef DEBUG str(r3, MemOperand(ip)); @@ -1118,7 +1118,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, } stm(db_w, sp, r3.bit() | cp.bit() | fp.bit() | lr.bit()); // Save the current handler as the next handler. - mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); ldr(r1, MemOperand(r3)); push(r1); // Link this handler as the new current one. @@ -1134,7 +1134,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, mov(r7, Operand(0, RelocInfo::NONE)); // NULL frame pointer. stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | lr.bit()); // Save the current handler as the next handler. - mov(r7, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + mov(r7, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); ldr(r6, MemOperand(r7)); push(r6); // Link this handler as the new current one. @@ -1146,7 +1146,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, void MacroAssembler::PopTryHandler() { STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); pop(r1); - mov(ip, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + mov(ip, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); str(r1, MemOperand(ip)); } @@ -1166,7 +1166,7 @@ void MacroAssembler::Throw(Register value) { } // Drop the sp to the top of the handler. - mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); ldr(sp, MemOperand(r3)); // Restore the next handler. @@ -1206,7 +1206,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, } // Drop sp to the top stack handler. - mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); ldr(sp, MemOperand(r3)); // Unwind the handlers until the ENTRY handler is found. @@ -1230,7 +1230,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, if (type == OUT_OF_MEMORY) { // Set external caught exception to false. ExternalReference external_caught( - Isolate::k_external_caught_exception_address, isolate()); + Isolate::kExternalCaughtExceptionAddress, isolate()); mov(r0, Operand(false, RelocInfo::NONE)); mov(r2, Operand(external_caught)); str(r0, MemOperand(r2)); @@ -1238,7 +1238,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, // Set pending exception and r0 to out of memory exception. Failure* out_of_memory = Failure::OutOfMemoryException(); mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); - mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, + mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate()))); str(r0, MemOperand(r2)); } @@ -1421,7 +1421,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss, const int kDetailsOffset = NumberDictionary::kElementsStartOffset + 2 * kPointerSize; ldr(t1, FieldMemOperand(t2, kDetailsOffset)); - tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask()))); + tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); b(ne, miss); // Get the value at the masked, scaled index and return. @@ -1793,7 +1793,7 @@ void MacroAssembler::CompareRoot(Register obj, void MacroAssembler::CheckFastElements(Register map, Register scratch, Label* fail) { - STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); + STATIC_ASSERT(FAST_ELEMENTS == 0); ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue)); b(hi, fail); diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h index 9d66359625..6084fde2d3 100644 --- a/deps/v8/src/arm/macro-assembler-arm.h +++ b/deps/v8/src/arm/macro-assembler-arm.h @@ -596,9 +596,7 @@ class MacroAssembler: public Assembler { // Compare instance type in a map. map contains a valid map object whose // object type should be compared with the given type. This both - // sets the flags and leaves the object type in the type_reg register. It - // leaves the heap object in the heap_object register unless the heap_object - // register is the same register as type_reg. + // sets the flags and leaves the object type in the type_reg register. void CompareInstanceType(Register map, Register type_reg, InstanceType type); diff --git a/deps/v8/src/arm/regexp-macro-assembler-arm.h b/deps/v8/src/arm/regexp-macro-assembler-arm.h index 0e653868b6..5c8ed0693f 100644 --- a/deps/v8/src/arm/regexp-macro-assembler-arm.h +++ b/deps/v8/src/arm/regexp-macro-assembler-arm.h @@ -116,6 +116,7 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler { static int CheckStackGuardState(Address* return_address, Code* re_code, Address re_frame); + private: // Offsets from frame_pointer() of function parameters and stored registers. static const int kFramePointer = 0; diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc index 5345892925..f8565924b1 100644 --- a/deps/v8/src/arm/stub-cache-arm.cc +++ b/deps/v8/src/arm/stub-cache-arm.cc @@ -3099,7 +3099,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { // -- r1 : receiver // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(r1, @@ -3193,7 +3193,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { // -- r3 : scratch // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; MaybeObject* maybe_stub = KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); @@ -3438,25 +3438,25 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( } -static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) { +static bool IsElementTypeSigned(ElementsKind elements_kind) { switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: return true; - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: return false; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); return false; } @@ -3466,7 +3466,7 @@ static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) { void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ---------- S t a t e -------------- // -- lr : return address // -- r0 : key @@ -3501,24 +3501,24 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( Register value = r2; switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ ldrsb(value, MemOperand(r3, key, LSR, 1)); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ ldrb(value, MemOperand(r3, key, LSR, 1)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: __ ldrsh(value, MemOperand(r3, key, LSL, 0)); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ ldrh(value, MemOperand(r3, key, LSL, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ ldr(value, MemOperand(r3, key, LSL, 1)); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); __ add(r2, r3, Operand(key, LSL, 1)); @@ -3527,7 +3527,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ ldr(value, MemOperand(r3, key, LSL, 1)); } break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); __ add(r2, r3, Operand(key, LSL, 2)); @@ -3539,10 +3539,10 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ ldr(r3, MemOperand(r4, Register::kSizeInBytes)); } break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3556,7 +3556,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // d0: value (if VFP3 is supported) // r2/r3: value (if VFP3 is not supported) - if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { + if (elements_kind == EXTERNAL_INT_ELEMENTS) { // For the Int and UnsignedInt array types, we need to see whether // the value can be represented in a Smi. If not, we need to convert // it to a HeapNumber. @@ -3600,7 +3600,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); __ Ret(); } - } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { + } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { // The test is different for unsigned int values. Since we need // the value to be in the range of a positive smi, we can't // handle either of the top two bits being set in the value. @@ -3665,7 +3665,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(r0, r4); __ Ret(); } - } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. if (CpuFeatures::IsSupported(VFP3)) { @@ -3735,7 +3735,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(r0, r3); __ Ret(); } - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); // Allocate a HeapNumber for the result. Don't use r0 and r1 as @@ -3792,7 +3792,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ---------- S t a t e -------------- // -- r0 : value // -- r1 : key @@ -3824,7 +3824,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // Handle both smis and HeapNumbers in the fast path. Go to the // runtime for all other kinds of values. // r3: external array. - if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { // Double to pixel conversion is only implemented in the runtime for now. __ JumpIfNotSmi(value, &slow); } else { @@ -3836,29 +3836,29 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // r3: base pointer of external storage. // r5: value (integer). switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: // Clamp the value to [0..255]. __ Usat(r5, 8, Operand(r5)); __ strb(r5, MemOperand(r3, key, LSR, 1)); break; - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(r5, MemOperand(r3, key, LSR, 1)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(r5, MemOperand(r3, key, LSL, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(r5, MemOperand(r3, key, LSL, 1)); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: // Perform int-to-float conversion and store to memory. __ SmiUntag(r4, key); StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: __ add(r3, r3, Operand(key, LSL, 2)); // r3: effective address of the double element FloatingPointHelper::Destination destination; @@ -3879,10 +3879,10 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ str(r7, MemOperand(r3, Register::kSizeInBytes)); } break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3890,7 +3890,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // Entry registers are intact, r0 holds the value which is the return value. __ Ret(); - if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { // r3: external array. __ bind(&check_heap_number); __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); @@ -3906,7 +3906,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( if (CpuFeatures::IsSupported(VFP3)) { CpuFeatures::Scope scope(VFP3); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { // vldr requires offset to be a multiple of 4 so we can not // include -kHeapObjectTag into it. __ sub(r5, r0, Operand(kHeapObjectTag)); @@ -3914,7 +3914,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ add(r5, r3, Operand(key, LSL, 1)); __ vcvt_f32_f64(s0, d0); __ vstr(s0, r5, 0); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ sub(r5, r0, Operand(kHeapObjectTag)); __ vldr(d0, r5, HeapNumber::kValueOffset); __ add(r5, r3, Operand(key, LSL, 2)); @@ -3927,25 +3927,25 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ EmitECMATruncate(r5, d0, s2, r6, r7, r9); switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(r5, MemOperand(r3, key, LSR, 1)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(r5, MemOperand(r3, key, LSL, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(r5, MemOperand(r3, key, LSL, 1)); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3959,7 +3959,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset)); __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset)); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { Label done, nan_or_infinity_or_zero; static const int kMantissaInHiWordShift = kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; @@ -4011,7 +4011,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift)); __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift)); __ b(&done); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ add(r7, r3, Operand(key, LSL, 2)); // r7: effective address of destination element. __ str(r6, MemOperand(r7, 0)); @@ -4066,25 +4066,25 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ bind(&done); switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ strb(r5, MemOperand(r3, key, LSR, 1)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ strh(r5, MemOperand(r3, key, LSL, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ str(r5, MemOperand(r3, key, LSL, 1)); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } diff --git a/deps/v8/src/array.js b/deps/v8/src/array.js index 32a370fda8..4dd23c8bb4 100644 --- a/deps/v8/src/array.js +++ b/deps/v8/src/array.js @@ -208,7 +208,7 @@ function ConvertToLocaleString(e) { // Call ToString if toLocaleString is not a function. // See issue 877615. var e_obj = ToObject(e); - if (IS_FUNCTION(e_obj.toLocaleString)) + if (IS_SPEC_FUNCTION(e_obj.toLocaleString)) return ToString(e_obj.toLocaleString()); else return ToString(e); @@ -730,7 +730,7 @@ function ArraySort(comparefn) { // In-place QuickSort algorithm. // For short (length <= 22) arrays, insertion sort is used for efficiency. - if (!IS_FUNCTION(comparefn)) { + if (!IS_SPEC_FUNCTION(comparefn)) { comparefn = function (x, y) { if (x === y) return 0; if (%_IsSmi(x) && %_IsSmi(y)) { @@ -993,7 +993,7 @@ function ArrayFilter(f, receiver) { ["Array.prototype.filter"]); } - if (!IS_FUNCTION(f)) { + if (!IS_SPEC_FUNCTION(f)) { throw MakeTypeError('called_non_callable', [ f ]); } if (IS_NULL_OR_UNDEFINED(receiver)) { @@ -1022,7 +1022,7 @@ function ArrayForEach(f, receiver) { ["Array.prototype.forEach"]); } - if (!IS_FUNCTION(f)) { + if (!IS_SPEC_FUNCTION(f)) { throw MakeTypeError('called_non_callable', [ f ]); } if (IS_NULL_OR_UNDEFINED(receiver)) { @@ -1048,7 +1048,7 @@ function ArraySome(f, receiver) { ["Array.prototype.some"]); } - if (!IS_FUNCTION(f)) { + if (!IS_SPEC_FUNCTION(f)) { throw MakeTypeError('called_non_callable', [ f ]); } if (IS_NULL_OR_UNDEFINED(receiver)) { @@ -1073,7 +1073,7 @@ function ArrayEvery(f, receiver) { ["Array.prototype.every"]); } - if (!IS_FUNCTION(f)) { + if (!IS_SPEC_FUNCTION(f)) { throw MakeTypeError('called_non_callable', [ f ]); } if (IS_NULL_OR_UNDEFINED(receiver)) { @@ -1097,7 +1097,7 @@ function ArrayMap(f, receiver) { ["Array.prototype.map"]); } - if (!IS_FUNCTION(f)) { + if (!IS_SPEC_FUNCTION(f)) { throw MakeTypeError('called_non_callable', [ f ]); } if (IS_NULL_OR_UNDEFINED(receiver)) { @@ -1245,7 +1245,7 @@ function ArrayReduce(callback, current) { ["Array.prototype.reduce"]); } - if (!IS_FUNCTION(callback)) { + if (!IS_SPEC_FUNCTION(callback)) { throw MakeTypeError('called_non_callable', [callback]); } @@ -1281,7 +1281,7 @@ function ArrayReduceRight(callback, current) { ["Array.prototype.reduceRight"]); } - if (!IS_FUNCTION(callback)) { + if (!IS_SPEC_FUNCTION(callback)) { throw MakeTypeError('called_non_callable', [callback]); } var i = ToUint32(this.length) - 1; diff --git a/deps/v8/src/ast.cc b/deps/v8/src/ast.cc index a44d9ee460..418cc432b6 100644 --- a/deps/v8/src/ast.cc +++ b/deps/v8/src/ast.cc @@ -969,7 +969,7 @@ class RegExpUnparser: public RegExpVisitor { public: RegExpUnparser(); void VisitCharacterRange(CharacterRange that); - SmartPointer<const char> ToString() { return stream_.ToCString(); } + SmartArrayPointer<const char> ToString() { return stream_.ToCString(); } #define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, void* data); FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) #undef MAKE_CASE @@ -1124,7 +1124,7 @@ void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) { } -SmartPointer<const char> RegExpTree::ToString() { +SmartArrayPointer<const char> RegExpTree::ToString() { RegExpUnparser unparser; Accept(&unparser, NULL); return unparser.ToString(); diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h index 2b32cdfa91..b56205f9a6 100644 --- a/deps/v8/src/ast.h +++ b/deps/v8/src/ast.h @@ -1775,7 +1775,7 @@ class RegExpTree: public ZoneObject { // expression. virtual Interval CaptureRegisters() { return Interval::Empty(); } virtual void AppendToText(RegExpText* text); - SmartPointer<const char> ToString(); + SmartArrayPointer<const char> ToString(); #define MAKE_ASTYPE(Name) \ virtual RegExp##Name* As##Name(); \ virtual bool Is##Name(); diff --git a/deps/v8/src/bignum.h b/deps/v8/src/bignum.h index 1d2bff61a5..dcc4fa702a 100644 --- a/deps/v8/src/bignum.h +++ b/deps/v8/src/bignum.h @@ -92,6 +92,7 @@ class Bignum { static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) { return PlusCompare(a, b, c) < 0; } + private: typedef uint32_t Chunk; typedef uint64_t DoubleChunk; diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index 7abd45cac0..f07e625ec0 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -1067,7 +1067,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<Map> new_map = factory->CopyMapDropTransitions(old_map); new_map->set_pre_allocated_property_fields(2); Handle<JSObject> result = factory->NewJSObjectFromMap(new_map); - new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); + new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS); // Set up a well-formed parameter map to make assertions happy. Handle<FixedArray> elements = factory->NewFixedArray(2); elements->set_map(heap->non_strict_arguments_elements_map()); @@ -2062,7 +2062,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, break; } case MAP_TRANSITION: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: // Ignore non-properties. diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc index d403a951cf..e6a0699f07 100644 --- a/deps/v8/src/builtins.cc +++ b/deps/v8/src/builtins.cc @@ -1583,7 +1583,6 @@ void Builtins::InitBuiltinFunctionTable() { functions->s_name = #aname; \ functions->name = k##aname; \ functions->flags = Code::ComputeFlags(Code::kind, \ - NOT_IN_LOOP, \ state, \ extra); \ functions->extra_args = NO_EXTRA_ARGUMENTS; \ diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h index f9a5a13bd9..31090d3a08 100644 --- a/deps/v8/src/builtins.h +++ b/deps/v8/src/builtins.h @@ -238,6 +238,8 @@ enum BuiltinExtraArguments { V(FILTER_KEY, 1) \ V(CALL_NON_FUNCTION, 0) \ V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \ + V(CALL_FUNCTION_PROXY, 1) \ + V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \ V(TO_OBJECT, 0) \ V(TO_NUMBER, 0) \ V(TO_STRING, 0) \ diff --git a/deps/v8/src/cached-powers.h b/deps/v8/src/cached-powers.h index 2ae56196a3..88df22260c 100644 --- a/deps/v8/src/cached-powers.h +++ b/deps/v8/src/cached-powers.h @@ -35,7 +35,6 @@ namespace internal { class PowersOfTenCache { public: - // Not all powers of ten are cached. The decimal exponent of two neighboring // cached numbers will differ by kDecimalExponentDistance. static const int kDecimalExponentDistance; diff --git a/deps/v8/src/circular-queue-inl.h b/deps/v8/src/circular-queue-inl.h index 349f22299a..373bf6092a 100644 --- a/deps/v8/src/circular-queue-inl.h +++ b/deps/v8/src/circular-queue-inl.h @@ -1,4 +1,4 @@ -// Copyright 2010 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -25,8 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef V8_CIRCULAR_BUFFER_INL_H_ -#define V8_CIRCULAR_BUFFER_INL_H_ +#ifndef V8_CIRCULAR_QUEUE_INL_H_ +#define V8_CIRCULAR_QUEUE_INL_H_ #include "circular-queue.h" @@ -50,4 +50,4 @@ void SamplingCircularQueue::WrapPositionIfNeeded( } } // namespace v8::internal -#endif // V8_CIRCULAR_BUFFER_INL_H_ +#endif // V8_CIRCULAR_QUEUE_INL_H_ diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc index 5535d171be..00da4cba62 100644 --- a/deps/v8/src/code-stubs.cc +++ b/deps/v8/src/code-stubs.cc @@ -61,7 +61,7 @@ void CodeStub::GenerateCode(MacroAssembler* masm) { } -SmartPointer<const char> CodeStub::GetName() { +SmartArrayPointer<const char> CodeStub::GetName() { char buffer[100]; NoAllocationStringAllocator allocator(buffer, static_cast<unsigned>(sizeof(buffer))); @@ -75,7 +75,7 @@ void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) { code->set_major_key(MajorKey()); Isolate* isolate = masm->isolate(); - SmartPointer<const char> name = GetName(); + SmartArrayPointer<const char> name = GetName(); PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name)); GDBJIT(AddCode(GDBJITInterface::STUB, *name, code)); Counters* counters = isolate->counters(); @@ -114,7 +114,6 @@ Handle<Code> CodeStub::GetCode() { // Copy the generated code into a heap object. Code::Flags flags = Code::ComputeFlags( static_cast<Code::Kind>(GetCodeKind()), - InLoop(), GetICState()); Handle<Code> new_object = factory->NewCode( desc, flags, masm.CodeObject(), NeedsImmovableCode()); @@ -152,7 +151,6 @@ MaybeObject* CodeStub::TryGetCode() { // Try to copy the generated code into a heap object. Code::Flags flags = Code::ComputeFlags( static_cast<Code::Kind>(GetCodeKind()), - InLoop(), GetICState()); Object* new_object; { MaybeObject* maybe_new_object = @@ -246,27 +244,27 @@ void InstanceofStub::PrintName(StringStream* stream) { void KeyedLoadElementStub::Generate(MacroAssembler* masm) { switch (elements_kind_) { - case JSObject::FAST_ELEMENTS: + case FAST_ELEMENTS: KeyedLoadStubCompiler::GenerateLoadFastElement(masm); break; - case JSObject::FAST_DOUBLE_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm); break; - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_); break; - case JSObject::DICTIONARY_ELEMENTS: + case DICTIONARY_ELEMENTS: KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); break; - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -275,28 +273,28 @@ void KeyedLoadElementStub::Generate(MacroAssembler* masm) { void KeyedStoreElementStub::Generate(MacroAssembler* masm) { switch (elements_kind_) { - case JSObject::FAST_ELEMENTS: + case FAST_ELEMENTS: KeyedStoreStubCompiler::GenerateStoreFastElement(masm, is_js_array_); break; - case JSObject::FAST_DOUBLE_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm, is_js_array_); break; - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_); break; - case JSObject::DICTIONARY_ELEMENTS: + case DICTIONARY_ELEMENTS: KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm); break; - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -316,17 +314,12 @@ void ArgumentsAccessStub::PrintName(StringStream* stream) { void CallFunctionStub::PrintName(StringStream* stream) { - const char* in_loop_name = NULL; // Make g++ happy. - switch (in_loop_) { - case NOT_IN_LOOP: in_loop_name = ""; break; - case IN_LOOP: in_loop_name = "_InLoop"; break; - } const char* flags_name = NULL; // Make g++ happy. switch (flags_) { case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break; case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break; } - stream->Add("CallFunctionStub_Args%d%s%s", argc_, in_loop_name, flags_name); + stream->Add("CallFunctionStub_Args%d%s", argc_, flags_name); } diff --git a/deps/v8/src/code-stubs.h b/deps/v8/src/code-stubs.h index 89e99a8d08..64c89b93d1 100644 --- a/deps/v8/src/code-stubs.h +++ b/deps/v8/src/code-stubs.h @@ -168,10 +168,6 @@ class CodeStub BASE_EMBEDDED { virtual Major MajorKey() = 0; virtual int MinorKey() = 0; - // The CallFunctionStub needs to override this so it can encode whether a - // lazily generated function should be fully optimized or not. - virtual InLoopFlag InLoop() { return NOT_IN_LOOP; } - // BinaryOpStub needs to override this. virtual int GetCodeKind(); @@ -181,7 +177,7 @@ class CodeStub BASE_EMBEDDED { } // Returns a name for logging/debugging purposes. - SmartPointer<const char> GetName(); + SmartArrayPointer<const char> GetName(); virtual void PrintName(StringStream* stream) { stream->Add("%s", MajorName(MajorKey(), false)); } @@ -646,8 +642,8 @@ class RegExpConstructResultStub: public CodeStub { class CallFunctionStub: public CodeStub { public: - CallFunctionStub(int argc, InLoopFlag in_loop, CallFunctionFlags flags) - : argc_(argc), in_loop_(in_loop), flags_(flags) { } + CallFunctionStub(int argc, CallFunctionFlags flags) + : argc_(argc), flags_(flags) { } void Generate(MacroAssembler* masm); @@ -657,26 +653,20 @@ class CallFunctionStub: public CodeStub { private: int argc_; - InLoopFlag in_loop_; CallFunctionFlags flags_; virtual void PrintName(StringStream* stream); // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. - class InLoopBits: public BitField<InLoopFlag, 0, 1> {}; - class FlagBits: public BitField<CallFunctionFlags, 1, 1> {}; - class ArgcBits: public BitField<int, 2, 32 - 2> {}; + class FlagBits: public BitField<CallFunctionFlags, 0, 1> {}; + class ArgcBits: public BitField<unsigned, 1, 32 - 1> {}; Major MajorKey() { return CallFunction; } int MinorKey() { // Encode the parameters in a unique 32 bit value. - return InLoopBits::encode(in_loop_) - | FlagBits::encode(flags_) - | ArgcBits::encode(argc_); + return FlagBits::encode(flags_) | ArgcBits::encode(argc_); } - InLoopFlag InLoop() { return in_loop_; } - bool ReceiverMightBeImplicit() { return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0; } @@ -860,7 +850,7 @@ class AllowStubCallsScope { class KeyedLoadElementStub : public CodeStub { public: - explicit KeyedLoadElementStub(JSObject::ElementsKind elements_kind) + explicit KeyedLoadElementStub(ElementsKind elements_kind) : elements_kind_(elements_kind) { } @@ -870,7 +860,7 @@ class KeyedLoadElementStub : public CodeStub { void Generate(MacroAssembler* masm); private: - JSObject::ElementsKind elements_kind_; + ElementsKind elements_kind_; DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub); }; @@ -879,20 +869,20 @@ class KeyedLoadElementStub : public CodeStub { class KeyedStoreElementStub : public CodeStub { public: KeyedStoreElementStub(bool is_js_array, - JSObject::ElementsKind elements_kind) + ElementsKind elements_kind) : is_js_array_(is_js_array), elements_kind_(elements_kind) { } Major MajorKey() { return KeyedStoreElement; } int MinorKey() { - return (is_js_array_ ? 0 : JSObject::kElementsKindCount) + elements_kind_; + return (is_js_array_ ? 0 : kElementsKindCount) + elements_kind_; } void Generate(MacroAssembler* masm); private: bool is_js_array_; - JSObject::ElementsKind elements_kind_; + ElementsKind elements_kind_; DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub); }; diff --git a/deps/v8/src/compilation-cache.h b/deps/v8/src/compilation-cache.h index 1fcf75313e..4339d22641 100644 --- a/deps/v8/src/compilation-cache.h +++ b/deps/v8/src/compilation-cache.h @@ -242,6 +242,7 @@ class CompilationCache { // cache during debugging to make sure new scripts are always compiled. void Enable(); void Disable(); + private: explicit CompilationCache(Isolate* isolate); ~CompilationCache(); diff --git a/deps/v8/src/compiler.h b/deps/v8/src/compiler.h index 8e92cf5a17..09aa23dec9 100644 --- a/deps/v8/src/compiler.h +++ b/deps/v8/src/compiler.h @@ -49,11 +49,11 @@ class CompilationInfo BASE_EMBEDDED { ASSERT(Isolate::Current() == isolate_); return isolate_; } - bool is_lazy() const { return (flags_ & IsLazy::mask()) != 0; } - bool is_eval() const { return (flags_ & IsEval::mask()) != 0; } - bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; } - bool is_strict_mode() const { return (flags_ & IsStrictMode::mask()) != 0; } - bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; } + bool is_lazy() const { return IsLazy::decode(flags_); } + bool is_eval() const { return IsEval::decode(flags_); } + bool is_global() const { return IsGlobal::decode(flags_); } + bool is_strict_mode() const { return IsStrictMode::decode(flags_); } + bool is_in_loop() const { return IsInLoop::decode(flags_); } FunctionLiteral* function() const { return function_; } Scope* scope() const { return scope_; } Handle<Code> code() const { return code_; } diff --git a/deps/v8/src/cpu-profiler-inl.h b/deps/v8/src/cpu-profiler-inl.h index 938b632214..4982197cab 100644 --- a/deps/v8/src/cpu-profiler-inl.h +++ b/deps/v8/src/cpu-profiler-inl.h @@ -51,11 +51,6 @@ void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) { } -void CodeDeleteEventRecord::UpdateCodeMap(CodeMap* code_map) { - code_map->DeleteCode(start); -} - - void SharedFunctionInfoMoveEventRecord::UpdateCodeMap(CodeMap* code_map) { code_map->MoveCode(from, to); } diff --git a/deps/v8/src/cpu-profiler.cc b/deps/v8/src/cpu-profiler.cc index bb480fc345..65490285e7 100644 --- a/deps/v8/src/cpu-profiler.cc +++ b/deps/v8/src/cpu-profiler.cc @@ -137,16 +137,6 @@ void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) { } -void ProfilerEventsProcessor::CodeDeleteEvent(Address from) { - CodeEventsContainer evt_rec; - CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_; - rec->type = CodeEventRecord::CODE_DELETE; - rec->order = ++enqueue_order_; - rec->start = from; - events_buffer_.Enqueue(evt_rec); -} - - void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from, Address to) { CodeEventsContainer evt_rec; @@ -425,7 +415,6 @@ void CpuProfiler::CodeMoveEvent(Address from, Address to) { void CpuProfiler::CodeDeleteEvent(Address from) { - Isolate::Current()->cpu_profiler()->processor_->CodeDeleteEvent(from); } diff --git a/deps/v8/src/cpu-profiler.h b/deps/v8/src/cpu-profiler.h index 4175e8f680..a71c0e0ab4 100644 --- a/deps/v8/src/cpu-profiler.h +++ b/deps/v8/src/cpu-profiler.h @@ -48,7 +48,6 @@ class TokenEnumerator; #define CODE_EVENTS_TYPE_LIST(V) \ V(CODE_CREATION, CodeCreateEventRecord) \ V(CODE_MOVE, CodeMoveEventRecord) \ - V(CODE_DELETE, CodeDeleteEventRecord) \ V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord) @@ -87,14 +86,6 @@ class CodeMoveEventRecord : public CodeEventRecord { }; -class CodeDeleteEventRecord : public CodeEventRecord { - public: - Address start; - - INLINE(void UpdateCodeMap(CodeMap* code_map)); -}; - - class SharedFunctionInfoMoveEventRecord : public CodeEventRecord { public: Address from; diff --git a/deps/v8/src/d8-debug.cc b/deps/v8/src/d8-debug.cc index 06622057b4..adefba7322 100644 --- a/deps/v8/src/d8-debug.cc +++ b/deps/v8/src/d8-debug.cc @@ -221,14 +221,14 @@ void RemoteDebugger::Run() { } -void RemoteDebugger::MessageReceived(i::SmartPointer<char> message) { +void RemoteDebugger::MessageReceived(i::SmartArrayPointer<char> message) { RemoteDebuggerEvent* event = new RemoteDebuggerEvent(RemoteDebuggerEvent::kMessage, message); AddEvent(event); } -void RemoteDebugger::KeyboardCommand(i::SmartPointer<char> command) { +void RemoteDebugger::KeyboardCommand(i::SmartArrayPointer<char> command) { RemoteDebuggerEvent* event = new RemoteDebuggerEvent(RemoteDebuggerEvent::kKeyboard, command); AddEvent(event); @@ -238,7 +238,7 @@ void RemoteDebugger::KeyboardCommand(i::SmartPointer<char> command) { void RemoteDebugger::ConnectionClosed() { RemoteDebuggerEvent* event = new RemoteDebuggerEvent(RemoteDebuggerEvent::kDisconnect, - i::SmartPointer<char>()); + i::SmartArrayPointer<char>()); AddEvent(event); } @@ -330,14 +330,14 @@ void RemoteDebugger::HandleKeyboardCommand(char* command) { void ReceiverThread::Run() { // Receive the connect message (with empty body). - i::SmartPointer<char> message = - i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn()); + i::SmartArrayPointer<char> message = + i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn()); ASSERT(*message == NULL); while (true) { // Receive a message. - i::SmartPointer<char> message = - i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn()); + i::SmartArrayPointer<char> message = + i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn()); if (*message == NULL) { remote_debugger_->ConnectionClosed(); return; @@ -361,7 +361,7 @@ void KeyboardThread::Run() { // Pass the keyboard command to the main thread. remote_debugger_->KeyboardCommand( - i::SmartPointer<char>(i::StrDup(command))); + i::SmartArrayPointer<char>(i::StrDup(command))); } } diff --git a/deps/v8/src/d8-debug.h b/deps/v8/src/d8-debug.h index 4e33e6f4c4..aeff3c121c 100644 --- a/deps/v8/src/d8-debug.h +++ b/deps/v8/src/d8-debug.h @@ -61,8 +61,8 @@ class RemoteDebugger { void Run(); // Handle events from the subordinate threads. - void MessageReceived(i::SmartPointer<char> message); - void KeyboardCommand(i::SmartPointer<char> command); + void MessageReceived(i::SmartArrayPointer<char> message); + void KeyboardCommand(i::SmartArrayPointer<char> command); void ConnectionClosed(); private: @@ -127,7 +127,7 @@ class KeyboardThread: public i::Thread { // Events processed by the main deubgger thread. class RemoteDebuggerEvent { public: - RemoteDebuggerEvent(int type, i::SmartPointer<char> data) + RemoteDebuggerEvent(int type, i::SmartArrayPointer<char> data) : type_(type), data_(data), next_(NULL) { ASSERT(type == kMessage || type == kKeyboard || type == kDisconnect); } @@ -144,7 +144,7 @@ class RemoteDebuggerEvent { RemoteDebuggerEvent* next() { return next_; } int type_; - i::SmartPointer<char> data_; + i::SmartArrayPointer<char> data_; RemoteDebuggerEvent* next_; friend class RemoteDebugger; diff --git a/deps/v8/src/d8-posix.cc b/deps/v8/src/d8-posix.cc index 658fd4ff07..289c3b0ae8 100644 --- a/deps/v8/src/d8-posix.cc +++ b/deps/v8/src/d8-posix.cc @@ -231,6 +231,7 @@ class ExecArgs { static const unsigned kMaxArgs = 1000; char** arg_array() { return exec_args_; } char* arg0() { return exec_args_[0]; } + private: char* exec_args_[kMaxArgs + 1]; }; diff --git a/deps/v8/src/d8-readline.cc b/deps/v8/src/d8-readline.cc index 08395e53de..71be933109 100644 --- a/deps/v8/src/d8-readline.cc +++ b/deps/v8/src/d8-readline.cc @@ -1,4 +1,4 @@ -// Copyright 2008 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -49,7 +49,7 @@ namespace v8 { class ReadLineEditor: public LineEditor { public: ReadLineEditor() : LineEditor(LineEditor::READLINE, "readline") { } - virtual i::SmartPointer<char> Prompt(const char* prompt); + virtual i::SmartArrayPointer<char> Prompt(const char* prompt); virtual bool Open(); virtual bool Close(); virtual void AddHistory(const char* str); @@ -72,6 +72,7 @@ bool ReadLineEditor::Open() { rl_completer_word_break_characters = kWordBreakCharacters; rl_bind_key('\t', rl_complete); using_history(); + stifle_history(Shell::kMaxHistoryEntries); return read_history(Shell::kHistoryFileName) == 0; } @@ -81,13 +82,25 @@ bool ReadLineEditor::Close() { } -i::SmartPointer<char> ReadLineEditor::Prompt(const char* prompt) { +i::SmartArrayPointer<char> ReadLineEditor::Prompt(const char* prompt) { char* result = readline(prompt); - return i::SmartPointer<char>(result); + return i::SmartArrayPointer<char>(result); } void ReadLineEditor::AddHistory(const char* str) { + // Do not record empty input. + if (strlen(str) == 0) return; + // Remove duplicate history entry. + history_set_pos(history_length-1); + if (current_history()) { + do { + if (strcmp(current_history()->line, str) == 0) { + remove_history(where_history()); + break; + } + } while (previous_history()); + } add_history(str); } @@ -105,7 +118,7 @@ char* ReadLineEditor::CompletionGenerator(const char* text, int state) { static unsigned current_index; static Persistent<Array> current_completions; if (state == 0) { - i::SmartPointer<char> full_text(i::StrNDup(rl_line_buffer, rl_point)); + i::SmartArrayPointer<char> full_text(i::StrNDup(rl_line_buffer, rl_point)); HandleScope scope; Handle<Array> completions = Shell::GetCompletions(String::New(text), String::New(*full_text)); diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc index 93b383d9ac..55f0d4c2ab 100644 --- a/deps/v8/src/d8.cc +++ b/deps/v8/src/d8.cc @@ -70,6 +70,7 @@ namespace v8 { #ifndef V8_SHARED LineEditor *LineEditor::first_ = NULL; const char* Shell::kHistoryFileName = ".d8_history"; +const int Shell::kMaxHistoryEntries = 1000; LineEditor::LineEditor(Type type, const char* name) @@ -95,19 +96,19 @@ LineEditor* LineEditor::Get() { class DumbLineEditor: public LineEditor { public: DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { } - virtual i::SmartPointer<char> Prompt(const char* prompt); + virtual i::SmartArrayPointer<char> Prompt(const char* prompt); }; static DumbLineEditor dumb_line_editor; -i::SmartPointer<char> DumbLineEditor::Prompt(const char* prompt) { +i::SmartArrayPointer<char> DumbLineEditor::Prompt(const char* prompt) { static const int kBufferSize = 256; char buffer[kBufferSize]; printf("%s", prompt); char* str = fgets(buffer, kBufferSize, stdin); - return i::SmartPointer<char>(str ? i::StrDup(str) : str); + return i::SmartArrayPointer<char>(str ? i::StrDup(str) : str); } @@ -117,6 +118,7 @@ CounterCollection Shell::local_counters_; CounterCollection* Shell::counters_ = &local_counters_; i::Mutex* Shell::context_mutex_(i::OS::CreateMutex()); Persistent<Context> Shell::utility_context_; +LineEditor* Shell::console = NULL; #endif // V8_SHARED Persistent<Context> Shell::evaluation_context_; @@ -203,7 +205,7 @@ Handle<Value> Shell::Write(const Arguments& args) { int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout)); if (n != str.length()) { printf("Error in fwrite\n"); - exit(1); + Exit(1); } } return Undefined(); @@ -271,7 +273,7 @@ Handle<Value> Shell::Load(const Arguments& args) { if (source.IsEmpty()) { return ThrowException(String::New("Error loading file")); } - if (!ExecuteString(source, String::New(*file), false, false)) { + if (!ExecuteString(source, String::New(*file), false, true)) { return ThrowException(String::New("Error executing file")); } } @@ -295,18 +297,20 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, size_t length = 0; if (args[0]->IsUint32()) { length = args[0]->Uint32Value(); - } else if (args[0]->IsNumber()) { - double raw_length = args[0]->NumberValue(); + } else { + Local<Number> number = args[0]->ToNumber(); + if (number.IsEmpty() || !number->IsNumber()) { + return ThrowException(String::New("Array length must be a number.")); + } + int32_t raw_length = number->ToInt32()->Int32Value(); if (raw_length < 0) { return ThrowException(String::New("Array length must not be negative.")); } - if (raw_length > kMaxLength) { + if (raw_length > static_cast<int32_t>(kMaxLength)) { return ThrowException( String::New("Array length exceeds maximum length.")); } length = static_cast<size_t>(raw_length); - } else { - return ThrowException(String::New("Array length must be a number.")); } if (length > static_cast<size_t>(kMaxLength)) { return ThrowException(String::New("Array length exceeds maximum length.")); @@ -439,6 +443,7 @@ void Shell::ReportException(v8::TryCatch* try_catch) { printf("%s\n", stack_trace_string); } } + printf("\n"); } @@ -518,7 +523,7 @@ void Shell::MapCounters(const char* name) { NULL : counters_file_->memory(); if (memory == NULL) { printf("Could not map counters file %s\n", name); - exit(1); + Exit(1); } counters_ = static_cast<CounterCollection*>(memory); V8::SetCounterFunction(LookupCounter); @@ -715,7 +720,7 @@ void Shell::Initialize() { int bz2_result = startup_data_decompressor.Decompress(); if (bz2_result != BZ_OK) { fprintf(stderr, "bzip error code: %d\n", bz2_result); - exit(1); + Exit(1); } #endif @@ -777,8 +782,18 @@ Persistent<Context> Shell::CreateEvaluationContext() { } +void Shell::Exit(int exit_code) { + // Use _exit instead of exit to avoid races between isolate + // threads and static destructors. + fflush(stdout); + fflush(stderr); + _exit(exit_code); +} + + #ifndef V8_SHARED void Shell::OnExit() { + if (console != NULL) console->Close(); if (i::FLAG_dump_counters) { printf("+----------------------------------------+-------------+\n"); printf("| Name | Value |\n"); @@ -883,20 +898,19 @@ void Shell::RunShell() { HandleScope outer_scope; Handle<String> name = String::New("(d8)"); #ifndef V8_SHARED - LineEditor* editor = LineEditor::Get(); - printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name()); + console = LineEditor::Get(); + printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name()); if (i::FLAG_debugger) { printf("JavaScript debugger enabled\n"); } - editor->Open(); + console->Open(); while (true) { - i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt); + i::SmartArrayPointer<char> input = console->Prompt(Shell::kPrompt); if (input.is_empty()) break; - editor->AddHistory(*input); + console->AddHistory(*input); HandleScope inner_scope; ExecuteString(String::New(*input), name, true, true); } - editor->Close(); #else printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion()); static const int kBufferSize = 256; @@ -915,18 +929,24 @@ void Shell::RunShell() { #ifndef V8_SHARED class ShellThread : public i::Thread { public: - ShellThread(int no, i::Vector<const char> files) + // Takes ownership of the underlying char array of |files|. + ShellThread(int no, char* files) : Thread("d8:ShellThread"), no_(no), files_(files) { } + + ~ShellThread() { + delete[] files_; + } + virtual void Run(); private: int no_; - i::Vector<const char> files_; + char* files_; }; void ShellThread::Run() { - char* ptr = const_cast<char*>(files_.start()); + char* ptr = files_; while ((ptr != NULL) && (*ptr != '\0')) { // For each newline-separated line. char* next_line = ReadLine(ptr); @@ -939,23 +959,24 @@ void ShellThread::Run() { // Prepare the context for this thread. Locker locker; - HandleScope scope; + HandleScope outer_scope; Persistent<Context> thread_context = Shell::CreateEvaluationContext(); Context::Scope context_scope(thread_context); while ((ptr != NULL) && (*ptr != '\0')) { + HandleScope inner_scope; char* filename = ptr; ptr = ReadWord(ptr); // Skip empty strings. if (strlen(filename) == 0) { - break; + continue; } Handle<String> str = Shell::ReadFile(filename); if (str.IsEmpty()) { - printf("WARNING: %s not found\n", filename); - break; + printf("File '%s' not found\n", filename); + Shell::Exit(1); } Shell::ExecuteString(str, String::New(filename), false, false); @@ -968,12 +989,15 @@ void ShellThread::Run() { #endif // V8_SHARED -void SourceGroup::ExitShell(int exit_code) { - // Use _exit instead of exit to avoid races between isolate - // threads and static destructors. - fflush(stdout); - fflush(stderr); - _exit(exit_code); +SourceGroup::~SourceGroup() { +#ifndef V8_SHARED + delete next_semaphore_; + next_semaphore_ = NULL; + delete done_semaphore_; + done_semaphore_ = NULL; + delete thread_; + thread_ = NULL; +#endif // V8_SHARED } @@ -986,8 +1010,7 @@ void SourceGroup::Execute() { Handle<String> file_name = String::New("unnamed"); Handle<String> source = String::New(argv_[i + 1]); if (!Shell::ExecuteString(source, file_name, false, true)) { - ExitShell(1); - return; + Shell::Exit(1); } ++i; } else if (arg[0] == '-') { @@ -999,12 +1022,10 @@ void SourceGroup::Execute() { Handle<String> source = ReadFile(arg); if (source.IsEmpty()) { printf("Error reading '%s'\n", arg); - ExitShell(1); - return; + Shell::Exit(1); } if (!Shell::ExecuteString(source, file_name, false, true)) { - ExitShell(1); - return; + Shell::Exit(1); } } } @@ -1037,7 +1058,7 @@ i::Thread::Options SourceGroup::GetThreadOptions() { void SourceGroup::ExecuteInThread() { Isolate* isolate = Isolate::New(); do { - if (!next_semaphore_.is_empty()) next_semaphore_->Wait(); + if (next_semaphore_ != NULL) next_semaphore_->Wait(); { Isolate::Scope iscope(isolate); Locker lock(isolate); @@ -1049,15 +1070,15 @@ void SourceGroup::ExecuteInThread() { } context.Dispose(); } - if (!done_semaphore_.is_empty()) done_semaphore_->Signal(); + if (done_semaphore_ != NULL) done_semaphore_->Signal(); } while (!Shell::options.last_run); isolate->Dispose(); } void SourceGroup::StartExecuteInThread() { - if (thread_.is_empty()) { - thread_ = i::SmartPointer<i::Thread>(new IsolateThread(this)); + if (thread_ == NULL) { + thread_ = new IsolateThread(this); thread_->Start(); } next_semaphore_->Signal(); @@ -1065,7 +1086,7 @@ void SourceGroup::StartExecuteInThread() { void SourceGroup::WaitForThread() { - if (thread_.is_empty()) return; + if (thread_ == NULL) return; if (Shell::options.last_run) { thread_->Join(); } else { @@ -1140,14 +1161,18 @@ bool Shell::SetOptions(int argc, char* argv[]) { return false; #endif // V8_SHARED options.num_isolates++; + } else if (strcmp(argv[i], "-p") == 0) { +#ifdef V8_SHARED + printf("D8 with shared library does not support multi-threading\n"); + return false; +#else + options.num_parallel_files++; +#endif // V8_SHARED } #ifdef V8_SHARED else if (strcmp(argv[i], "--dump-counters") == 0) { printf("D8 with shared library does not include counters\n"); return false; - } else if (strcmp(argv[i], "-p") == 0) { - printf("D8 with shared library does not support multi-threading\n"); - return false; } else if (strcmp(argv[i], "--debugger") == 0) { printf("Javascript debugger not included\n"); return false; @@ -1157,6 +1182,8 @@ bool Shell::SetOptions(int argc, char* argv[]) { #ifndef V8_SHARED // Run parallel threads if we are not using --isolate + options.parallel_files = new char*[options.num_parallel_files]; + int parallel_files_set = 0; for (int i = 1; i < argc; i++) { if (argv[i] == NULL) continue; if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) { @@ -1165,25 +1192,21 @@ bool Shell::SetOptions(int argc, char* argv[]) { return false; } argv[i] = NULL; - if (options.parallel_files == NULL) { - options.parallel_files = new i::List<i::Vector<const char> >(); - } - int size = 0; - const char* files = ReadChars(argv[++i], &size); - if (files == NULL) { - printf("-p option incomplete\n"); - return false; - } + i++; + options.parallel_files[parallel_files_set] = argv[i]; + parallel_files_set++; argv[i] = NULL; - options.parallel_files->Add(i::Vector<const char>(files, size)); - delete[] files; } } + if (parallel_files_set != options.num_parallel_files) { + printf("-p requires a file containing a list of files as parameter\n"); + return false; + } #endif // V8_SHARED v8::V8::SetFlagsFromCommandLine(&argc, argv, true); - // set up isolated source groups + // Set up isolated source groups. options.isolate_sources = new SourceGroup[options.num_isolates]; SourceGroup* current = options.isolate_sources; current->Begin(argv, 1); @@ -1206,14 +1229,22 @@ bool Shell::SetOptions(int argc, char* argv[]) { int Shell::RunMain(int argc, char* argv[]) { #ifndef V8_SHARED i::List<i::Thread*> threads(1); - if (options.parallel_files != NULL) - for (int i = 0; i < options.parallel_files->length(); i++) { - i::Vector<const char> files = options.parallel_files->at(i); + if (options.parallel_files != NULL) { + for (int i = 0; i < options.num_parallel_files; i++) { + char* files = NULL; + { Locker lock(Isolate::GetCurrent()); + int size = 0; + files = ReadChars(options.parallel_files[i], &size); + } + if (files == NULL) { + printf("File list '%s' not found\n", options.parallel_files[i]); + Exit(1); + } ShellThread* thread = new ShellThread(threads.length(), files); thread->Start(); threads.Add(thread); } - + } for (int i = 1; i < options.num_isolates; ++i) { options.isolate_sources[i].StartExecuteInThread(); } @@ -1235,8 +1266,7 @@ int Shell::RunMain(int argc, char* argv[]) { #ifndef V8_SHARED // Start preemption if threads have been created and preemption is enabled. - if (options.parallel_files != NULL - && threads.length() > 0 + if (threads.length() > 0 && options.use_preemption) { Locker::StartPreemption(options.preemption_interval); } @@ -1248,12 +1278,16 @@ int Shell::RunMain(int argc, char* argv[]) { options.isolate_sources[i].WaitForThread(); } - if (options.parallel_files != NULL) - for (int i = 0; i < threads.length(); i++) { - i::Thread* thread = threads[i]; - thread->Join(); - delete thread; - } + for (int i = 0; i < threads.length(); i++) { + i::Thread* thread = threads[i]; + thread->Join(); + delete thread; + } + + if (threads.length() > 0 && options.use_preemption) { + Locker lock; + Locker::StopPreemption(); + } #endif // V8_SHARED return 0; } diff --git a/deps/v8/src/d8.h b/deps/v8/src/d8.h index 3ec03907ed..15d8d5d50f 100644 --- a/deps/v8/src/d8.h +++ b/deps/v8/src/d8.h @@ -1,4 +1,4 @@ -// Copyright 2009 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -31,7 +31,7 @@ #ifndef V8_SHARED #include "allocation.h" #include "hashmap.h" -#include "smart-pointer.h" +#include "smart-array-pointer.h" #include "v8.h" #else #include "../include/v8.h" @@ -116,17 +116,43 @@ class CounterMap { #endif // V8_SHARED +#ifndef V8_SHARED +class LineEditor { + public: + enum Type { DUMB = 0, READLINE = 1 }; + LineEditor(Type type, const char* name); + virtual ~LineEditor() { } + + virtual i::SmartArrayPointer<char> Prompt(const char* prompt) = 0; + virtual bool Open() { return true; } + virtual bool Close() { return true; } + virtual void AddHistory(const char* str) { } + + const char* name() { return name_; } + static LineEditor* Get(); + private: + Type type_; + const char* name_; + LineEditor* next_; + static LineEditor* first_; +}; +#endif // V8_SHARED + + class SourceGroup { public: SourceGroup() : #ifndef V8_SHARED next_semaphore_(v8::internal::OS::CreateSemaphore(0)), done_semaphore_(v8::internal::OS::CreateSemaphore(0)), + thread_(NULL), #endif // V8_SHARED argv_(NULL), begin_offset_(0), end_offset_(0) {} + ~SourceGroup(); + void Begin(char** argv, int offset) { argv_ = const_cast<const char**>(argv); begin_offset_ = offset; @@ -157,9 +183,9 @@ class SourceGroup { static i::Thread::Options GetThreadOptions(); void ExecuteInThread(); - i::SmartPointer<i::Semaphore> next_semaphore_; - i::SmartPointer<i::Semaphore> done_semaphore_; - i::SmartPointer<i::Thread> thread_; + i::Semaphore* next_semaphore_; + i::Semaphore* done_semaphore_; + i::Thread* thread_; #endif // V8_SHARED void ExitShell(int exit_code); @@ -177,6 +203,7 @@ class ShellOptions { #ifndef V8_SHARED use_preemption(true), preemption_interval(10), + num_parallel_files(0), parallel_files(NULL), #endif // V8_SHARED script_executed(false), @@ -188,10 +215,18 @@ class ShellOptions { num_isolates(1), isolate_sources(NULL) { } + ~ShellOptions() { +#ifndef V8_SHARED + delete[] parallel_files; +#endif // V8_SHARED + delete[] isolate_sources; + } + #ifndef V8_SHARED bool use_preemption; int preemption_interval; - i::List< i::Vector<const char> >* parallel_files; + int num_parallel_files; + char** parallel_files; #endif // V8_SHARED bool script_executed; bool last_run; @@ -208,6 +243,7 @@ class Shell { #else class Shell : public i::AllStatic { #endif // V8_SHARED + public: static bool ExecuteString(Handle<String> source, Handle<Value> name, @@ -219,6 +255,7 @@ class Shell : public i::AllStatic { static Persistent<Context> CreateEvaluationContext(); static int RunMain(int argc, char* argv[]); static int Main(int argc, char* argv[]); + static void Exit(int exit_code); #ifndef V8_SHARED static Handle<Array> GetCompletions(Handle<String> text, @@ -299,6 +336,8 @@ class Shell : public i::AllStatic { static void AddOSMethods(Handle<ObjectTemplate> os_template); #ifndef V8_SHARED static const char* kHistoryFileName; + static const int kMaxHistoryEntries; + static LineEditor* console; #endif // V8_SHARED static const char* kPrompt; static ShellOptions options; @@ -329,29 +368,6 @@ class Shell : public i::AllStatic { }; -#ifndef V8_SHARED -class LineEditor { - public: - enum Type { DUMB = 0, READLINE = 1 }; - LineEditor(Type type, const char* name); - virtual ~LineEditor() { } - - virtual i::SmartPointer<char> Prompt(const char* prompt) = 0; - virtual bool Open() { return true; } - virtual bool Close() { return true; } - virtual void AddHistory(const char* str) { } - - const char* name() { return name_; } - static LineEditor* Get(); - private: - Type type_; - const char* name_; - LineEditor* next_; - static LineEditor* first_; -}; -#endif // V8_SHARED - - } // namespace v8 diff --git a/deps/v8/src/dateparser.h b/deps/v8/src/dateparser.h index 4777e35f66..27584ce39e 100644 --- a/deps/v8/src/dateparser.h +++ b/deps/v8/src/dateparser.h @@ -36,7 +36,6 @@ namespace internal { class DateParser : public AllStatic { public: - // Parse the string as a date. If parsing succeeds, return true after // filling out the output array as follows (all integers are Smis): // [0]: year @@ -234,6 +233,7 @@ class DateParser : public AllStatic { static DateToken Invalid() { return DateToken(kInvalidTokenTag, 0, -1); } + private: enum TagType { kInvalidTokenTag = -6, @@ -275,6 +275,7 @@ class DateParser : public AllStatic { } return false; } + private: DateToken Scan(); @@ -351,6 +352,7 @@ class DateParser : public AllStatic { static bool IsMinute(int x) { return Between(x, 0, 59); } static bool IsHour(int x) { return Between(x, 0, 23); } static bool IsSecond(int x) { return Between(x, 0, 59); } + private: static bool IsHour12(int x) { return Between(x, 0, 12); } static bool IsMillisecond(int x) { return Between(x, 0, 999); } diff --git a/deps/v8/src/debug-agent.cc b/deps/v8/src/debug-agent.cc index 520bc62926..591d0b3e46 100644 --- a/deps/v8/src/debug-agent.cc +++ b/deps/v8/src/debug-agent.cc @@ -169,7 +169,8 @@ void DebuggerAgentSession::Run() { while (true) { // Read data from the debugger front end. - SmartPointer<char> message = DebuggerAgentUtil::ReceiveMessage(client_); + SmartArrayPointer<char> message = + DebuggerAgentUtil::ReceiveMessage(client_); const char* msg = *message; bool is_closing_session = (msg == NULL); @@ -232,7 +233,7 @@ const int DebuggerAgentUtil::kContentLengthSize = StrLength(kContentLength); -SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) { +SmartArrayPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) { int received; // Read header. @@ -250,7 +251,7 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) { received = conn->Receive(&c, 1); if (received <= 0) { PrintF("Error %d\n", Socket::LastError()); - return SmartPointer<char>(); + return SmartArrayPointer<char>(); } // Add character to header buffer. @@ -287,12 +288,12 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) { if (strcmp(key, kContentLength) == 0) { // Get the content length value if present and within a sensible range. if (value == NULL || strlen(value) > 7) { - return SmartPointer<char>(); + return SmartArrayPointer<char>(); } for (int i = 0; value[i] != '\0'; i++) { // Bail out if illegal data. if (value[i] < '0' || value[i] > '9') { - return SmartPointer<char>(); + return SmartArrayPointer<char>(); } content_length = 10 * content_length + (value[i] - '0'); } @@ -304,7 +305,7 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) { // Return now if no body. if (content_length == 0) { - return SmartPointer<char>(); + return SmartArrayPointer<char>(); } // Read body. @@ -312,11 +313,11 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) { received = ReceiveAll(conn, buffer, content_length); if (received < content_length) { PrintF("Error %d\n", Socket::LastError()); - return SmartPointer<char>(); + return SmartArrayPointer<char>(); } buffer[content_length] = '\0'; - return SmartPointer<char>(buffer); + return SmartArrayPointer<char>(buffer); } diff --git a/deps/v8/src/debug-agent.h b/deps/v8/src/debug-agent.h index e167871977..a07fb0f49c 100644 --- a/deps/v8/src/debug-agent.h +++ b/deps/v8/src/debug-agent.h @@ -72,7 +72,7 @@ class DebuggerAgent: public Thread { void OnSessionClosed(DebuggerAgentSession* session); Isolate* isolate_; - SmartPointer<const char> name_; // Name of the embedding application. + SmartArrayPointer<const char> name_; // Name of the embedding application. int port_; // Port to use for the agent. Socket* server_; // Server socket for listen/accept. bool terminate_; // Termination flag. @@ -117,7 +117,7 @@ class DebuggerAgentUtil { static const char* const kContentLength; static const int kContentLengthSize; - static SmartPointer<char> ReceiveMessage(const Socket* conn); + static SmartArrayPointer<char> ReceiveMessage(const Socket* conn); static bool SendConnectMessage(const Socket* conn, const char* embedding_host); static bool SendMessage(const Socket* conn, const Vector<uint16_t> message); diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc index 2d58ce1f54..a229d39c3e 100644 --- a/deps/v8/src/debug.cc +++ b/deps/v8/src/debug.cc @@ -40,6 +40,7 @@ #include "global-handles.h" #include "ic.h" #include "ic-inl.h" +#include "list.h" #include "messages.h" #include "natives.h" #include "stub-cache.h" @@ -542,6 +543,7 @@ void Debug::ThreadInit() { thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.step_count_ = 0; thread_local_.last_fp_ = 0; + thread_local_.queued_step_count_ = 0; thread_local_.step_into_fp_ = 0; thread_local_.step_out_fp_ = 0; thread_local_.after_break_target_ = 0; @@ -957,14 +959,49 @@ Object* Debug::Break(Arguments args) { // Clear all current stepping setup. ClearStepping(); - // Notify the debug event listeners. - isolate_->debugger()->OnDebugBreak(break_points_hit, false); + if (thread_local_.queued_step_count_ > 0) { + // Perform queued steps + int step_count = thread_local_.queued_step_count_; + + // Clear queue + thread_local_.queued_step_count_ = 0; + + PrepareStep(StepNext, step_count); + } else { + // Notify the debug event listeners. + isolate_->debugger()->OnDebugBreak(break_points_hit, false); + } } else if (thread_local_.last_step_action_ != StepNone) { // Hold on to last step action as it is cleared by the call to // ClearStepping. StepAction step_action = thread_local_.last_step_action_; int step_count = thread_local_.step_count_; + // If StepNext goes deeper in code, StepOut until original frame + // and keep step count queued up in the meantime. + if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) { + // Count frames until target frame + int count = 0; + JavaScriptFrameIterator it(isolate_); + while (!it.done() && it.frame()->fp() != thread_local_.last_fp_) { + count++; + it.Advance(); + } + + // If we found original frame + if (it.frame()->fp() == thread_local_.last_fp_) { + if (step_count > 1) { + // Save old count and action to continue stepping after + // StepOut + thread_local_.queued_step_count_ = step_count - 1; + } + + // Set up for StepOut to reach target frame + step_action = StepOut; + step_count = count; + } + } + // Clear all current stepping setup. ClearStepping(); @@ -1105,6 +1142,8 @@ void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, int* source_position) { HandleScope scope(isolate_); + PrepareForBreakPoints(); + if (!EnsureDebugInfo(shared)) { // Return if retrieving debug info failed. return; @@ -1178,6 +1217,7 @@ void Debug::ClearAllBreakPoints() { void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { + PrepareForBreakPoints(); // Make sure the function has setup the debug info. if (!EnsureDebugInfo(shared)) { // Return if we failed to retrieve the debug info. @@ -1234,6 +1274,9 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) { void Debug::PrepareStep(StepAction step_action, int step_count) { HandleScope scope(isolate_); + + PrepareForBreakPoints(); + ASSERT(Debug::InDebugger()); // Remember this step action and count. @@ -1448,6 +1491,13 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { // steps before reporting break back to the debugger. bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, JavaScriptFrame* frame) { + // StepNext and StepOut shouldn't bring us deeper in code, so last frame + // shouldn't be a parent of current frame. + if (thread_local_.last_step_action_ == StepNext || + thread_local_.last_step_action_ == StepOut) { + if (frame->fp() < thread_local_.last_fp_) return true; + } + // If the step last action was step next or step in make sure that a new // statement is hit. if (thread_local_.last_step_action_ == StepNext || @@ -1676,20 +1726,64 @@ void Debug::ClearStepNext() { } +void Debug::PrepareForBreakPoints() { + // If preparing for the first break point make sure to deoptimize all + // functions as debugging does not work with optimized code. + if (!has_break_points_) { + Deoptimizer::DeoptimizeAll(); + + AssertNoAllocation no_allocation; + Builtins* builtins = isolate_->builtins(); + Code* lazy_compile = builtins->builtin(Builtins::kLazyCompile); + + // Find all non-optimized code functions with activation frames on + // the stack. + List<JSFunction*> active_functions(100); + for (JavaScriptFrameIterator it(isolate_); !it.done(); it.Advance()) { + JavaScriptFrame* frame = it.frame(); + if (frame->function()->IsJSFunction()) { + JSFunction* function = JSFunction::cast(frame->function()); + if (function->code()->kind() == Code::FUNCTION) + active_functions.Add(function); + } + } + active_functions.Sort(); + + // Scan the heap for all non-optimized functions which has no + // debug break slots. + HeapIterator iterator; + HeapObject* obj = NULL; + while (((obj = iterator.next()) != NULL)) { + if (obj->IsJSFunction()) { + JSFunction* function = JSFunction::cast(obj); + if (function->shared()->allows_lazy_compilation() && + function->shared()->script()->IsScript() && + function->code()->kind() == Code::FUNCTION && + !function->code()->has_debug_break_slots()) { + bool has_activation = + SortedListBSearch<JSFunction*>(active_functions, function) != -1; + if (!has_activation) { + function->set_code(lazy_compile); + function->shared()->set_code(lazy_compile); + } + } + } + } + } +} + + // Ensures the debug information is present for shared. bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { // Return if we already have the debug info for shared. - if (HasDebugInfo(shared)) return true; + if (HasDebugInfo(shared)) { + ASSERT(shared->is_compiled()); + return true; + } // Ensure shared in compiled. Return false if this failed. if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; - // If preparing for the first break point make sure to deoptimize all - // functions as debugging does not work with optimized code. - if (!has_break_points_) { - Deoptimizer::DeoptimizeAll(); - } - // Create the debug info object. Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); @@ -1739,6 +1833,8 @@ void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) { void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { HandleScope scope(isolate_); + PrepareForBreakPoints(); + // Get the executing function in which the debug break occurred. Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); @@ -1829,6 +1925,8 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { return false; } + PrepareForBreakPoints(); + // Get the executing function in which the debug break occurred. Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); diff --git a/deps/v8/src/debug.h b/deps/v8/src/debug.h index c614844ab5..a098040c0d 100644 --- a/deps/v8/src/debug.h +++ b/deps/v8/src/debug.h @@ -247,6 +247,8 @@ class Debug { static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); + void PrepareForBreakPoints(); + // Returns whether the operation succeeded. bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared); @@ -506,6 +508,9 @@ class Debug { // Frame pointer from last step next action. Address last_fp_; + // Number of queued steps left to perform before debug event. + int queued_step_count_; + // Frame pointer for frame from which step in was performed. Address step_into_fp_; @@ -1026,6 +1031,7 @@ class Debug_Address { return NULL; } } + private: Debug::AddressId id_; }; diff --git a/deps/v8/src/disassembler.cc b/deps/v8/src/disassembler.cc index 79076d6abc..1e67b4cb66 100644 --- a/deps/v8/src/disassembler.cc +++ b/deps/v8/src/disassembler.cc @@ -223,7 +223,7 @@ static int DecodeIt(FILE* f, HeapStringAllocator allocator; StringStream accumulator(&allocator); relocinfo.target_object()->ShortPrint(&accumulator); - SmartPointer<const char> obj_name = accumulator.ToCString(); + SmartArrayPointer<const char> obj_name = accumulator.ToCString(); out.AddFormatted(" ;; object: %s", *obj_name); } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { const char* reference_name = @@ -247,9 +247,6 @@ static int DecodeIt(FILE* f, PropertyType type = code->type(); out.AddFormatted(", %s", Code::PropertyType2String(type)); } - if (code->ic_in_loop() == IN_LOOP) { - out.AddFormatted(", in_loop"); - } if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) { out.AddFormatted(", argc = %d", code->arguments_count()); } diff --git a/deps/v8/src/elements.cc b/deps/v8/src/elements.cc index 1afc5dad5e..e4ecfe8dd6 100644 --- a/deps/v8/src/elements.cc +++ b/deps/v8/src/elements.cc @@ -401,7 +401,7 @@ class DictionaryElementsAccessor Heap* heap = isolate->heap(); FixedArray* backing_store = FixedArray::cast(obj->elements()); bool is_arguments = - (obj->GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); + (obj->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS); if (is_arguments) { backing_store = FixedArray::cast(backing_store->get(1)); } @@ -565,28 +565,28 @@ ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { switch (array->map()->instance_type()) { case FIXED_ARRAY_TYPE: if (array->IsDictionary()) { - return elements_accessors_[JSObject::DICTIONARY_ELEMENTS]; + return elements_accessors_[DICTIONARY_ELEMENTS]; } else { - return elements_accessors_[JSObject::FAST_ELEMENTS]; + return elements_accessors_[FAST_ELEMENTS]; } case EXTERNAL_BYTE_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_BYTE_ELEMENTS]; + return elements_accessors_[EXTERNAL_BYTE_ELEMENTS]; case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS]; + return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS]; case EXTERNAL_SHORT_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_SHORT_ELEMENTS]; + return elements_accessors_[EXTERNAL_SHORT_ELEMENTS]; case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS]; + return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS]; case EXTERNAL_INT_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_INT_ELEMENTS]; + return elements_accessors_[EXTERNAL_INT_ELEMENTS]; case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS]; + return elements_accessors_[EXTERNAL_UNSIGNED_INT_ELEMENTS]; case EXTERNAL_FLOAT_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_FLOAT_ELEMENTS]; + return elements_accessors_[EXTERNAL_FLOAT_ELEMENTS]; case EXTERNAL_DOUBLE_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_DOUBLE_ELEMENTS]; + return elements_accessors_[EXTERNAL_DOUBLE_ELEMENTS]; case EXTERNAL_PIXEL_ARRAY_TYPE: - return elements_accessors_[JSObject::EXTERNAL_PIXEL_ELEMENTS]; + return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS]; default: UNREACHABLE(); return NULL; diff --git a/deps/v8/src/elements.h b/deps/v8/src/elements.h index 3eae303ed1..851c8c3d97 100644 --- a/deps/v8/src/elements.h +++ b/deps/v8/src/elements.h @@ -54,8 +54,8 @@ class ElementsAccessor { Object* receiver) = 0; // Returns a shared ElementsAccessor for the specified ElementsKind. - static ElementsAccessor* ForKind(JSObject::ElementsKind elements_kind) { - ASSERT(elements_kind < JSObject::kElementsKindCount); + static ElementsAccessor* ForKind(ElementsKind elements_kind) { + ASSERT(elements_kind < kElementsKindCount); return elements_accessors_[elements_kind]; } diff --git a/deps/v8/src/execution.cc b/deps/v8/src/execution.cc index bdbdca81bb..f36d4e4911 100644 --- a/deps/v8/src/execution.cc +++ b/deps/v8/src/execution.cc @@ -149,12 +149,29 @@ Handle<Object> Execution::Call(Handle<Object> callable, Handle<Object> receiver, int argc, Object*** args, - bool* pending_exception) { + bool* pending_exception, + bool convert_receiver) { if (!callable->IsJSFunction()) { callable = TryGetFunctionDelegate(callable, pending_exception); if (*pending_exception) return callable; } Handle<JSFunction> func = Handle<JSFunction>::cast(callable); + + // In non-strict mode, convert receiver. + if (convert_receiver && !receiver->IsJSReceiver() && + !func->shared()->native() && !func->shared()->strict_mode()) { + if (receiver->IsUndefined() || receiver->IsNull()) { + Object* global = func->context()->global()->global_receiver(); + // Under some circumstances, 'global' can be the JSBuiltinsObject + // In that case, don't rewrite. + // (FWIW, the same holds for GetIsolate()->global()->global_receiver().) + if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global); + } else { + receiver = ToObject(receiver, pending_exception); + } + if (*pending_exception) return callable; + } + return Invoke(false, func, receiver, argc, args, pending_exception); } @@ -210,10 +227,17 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { // If you return a function from here, it will be called when an // attempt is made to call the given object as a function. + // If object is a function proxy, get its handler. Iterate if necessary. + Object* fun = *object; + while (fun->IsJSFunctionProxy()) { + fun = JSFunctionProxy::cast(fun)->call_trap(); + } + if (fun->IsJSFunction()) return Handle<Object>(fun); + // Objects created through the API can have an instance-call handler // that should be used when calling the object as a function. - if (object->IsHeapObject() && - HeapObject::cast(*object)->map()->has_instance_call_handler()) { + if (fun->IsHeapObject() && + HeapObject::cast(fun)->map()->has_instance_call_handler()) { return Handle<JSFunction>( isolate->global_context()->call_as_function_delegate()); } @@ -227,10 +251,17 @@ Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, ASSERT(!object->IsJSFunction()); Isolate* isolate = Isolate::Current(); + // If object is a function proxy, get its handler. Iterate if necessary. + Object* fun = *object; + while (fun->IsJSFunctionProxy()) { + fun = JSFunctionProxy::cast(fun)->call_trap(); + } + if (fun->IsJSFunction()) return Handle<Object>(fun); + // Objects created through the API can have an instance-call handler // that should be used when calling the object as a function. - if (object->IsHeapObject() && - HeapObject::cast(*object)->map()->has_instance_call_handler()) { + if (fun->IsHeapObject() && + HeapObject::cast(fun)->map()->has_instance_call_handler()) { return Handle<JSFunction>( isolate->global_context()->call_as_function_delegate()); } @@ -253,10 +284,17 @@ Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { // If you return a function from here, it will be called when an // attempt is made to call the given object as a constructor. + // If object is a function proxies, get its handler. Iterate if necessary. + Object* fun = *object; + while (fun->IsJSFunctionProxy()) { + fun = JSFunctionProxy::cast(fun)->call_trap(); + } + if (fun->IsJSFunction()) return Handle<Object>(fun); + // Objects created through the API can have an instance-call handler // that should be used when calling the object as a function. - if (object->IsHeapObject() && - HeapObject::cast(*object)->map()->has_instance_call_handler()) { + if (fun->IsHeapObject() && + HeapObject::cast(fun)->map()->has_instance_call_handler()) { return Handle<JSFunction>( isolate->global_context()->call_as_constructor_delegate()); } @@ -274,10 +312,17 @@ Handle<Object> Execution::TryGetConstructorDelegate( // If you return a function from here, it will be called when an // attempt is made to call the given object as a constructor. + // If object is a function proxies, get its handler. Iterate if necessary. + Object* fun = *object; + while (fun->IsJSFunctionProxy()) { + fun = JSFunctionProxy::cast(fun)->call_trap(); + } + if (fun->IsJSFunction()) return Handle<Object>(fun); + // Objects created through the API can have an instance-call handler // that should be used when calling the object as a function. - if (object->IsHeapObject() && - HeapObject::cast(*object)->map()->has_instance_call_handler()) { + if (fun->IsHeapObject() && + HeapObject::cast(fun)->map()->has_instance_call_handler()) { return Handle<JSFunction>( isolate->global_context()->call_as_constructor_delegate()); } @@ -553,7 +598,7 @@ Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) { Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { - if (obj->IsJSObject()) return obj; + if (obj->IsSpecObject()) return obj; RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc); } diff --git a/deps/v8/src/execution.h b/deps/v8/src/execution.h index bb5f804506..5cd7141fc2 100644 --- a/deps/v8/src/execution.h +++ b/deps/v8/src/execution.h @@ -53,11 +53,16 @@ class Execution : public AllStatic { // *pending_exception tells whether the invoke resulted in // a pending exception. // + // When convert_receiver is set, and the receiver is not an object, + // and the function called is not in strict mode, receiver is converted to + // an object. + // static Handle<Object> Call(Handle<Object> callable, Handle<Object> receiver, int argc, Object*** args, - bool* pending_exception); + bool* pending_exception, + bool convert_receiver = false); // Construct object from function, the caller supplies an array of // arguments. Arguments are Object* type. After function returns, diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc index ee5c37bf08..97289266e3 100644 --- a/deps/v8/src/factory.cc +++ b/deps/v8/src/factory.cc @@ -465,13 +465,13 @@ Handle<Map> Factory::GetSlowElementsMap(Handle<Map> src) { } -Handle<Map> Factory::GetExternalArrayElementsMap( +Handle<Map> Factory::GetElementsTransitionMap( Handle<Map> src, - ExternalArrayType array_type, + ElementsKind elements_kind, bool safe_to_add_transition) { CALL_HEAP_FUNCTION(isolate(), - src->GetExternalArrayElementsMap(array_type, - safe_to_add_transition), + src->GetElementsTransitionMap(elements_kind, + safe_to_add_transition), Map); } @@ -922,10 +922,19 @@ Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler, } -void Factory::BecomeJSObject(Handle<JSProxy> object) { +void Factory::BecomeJSObject(Handle<JSReceiver> object) { CALL_HEAP_FUNCTION_VOID( isolate(), - isolate()->heap()->ReinitializeJSProxyAsJSObject(*object)); + isolate()->heap()->ReinitializeJSReceiver( + *object, JS_OBJECT_TYPE, JSObject::kHeaderSize)); +} + + +void Factory::BecomeJSFunction(Handle<JSReceiver> object) { + CALL_HEAP_FUNCTION_VOID( + isolate(), + isolate()->heap()->ReinitializeJSReceiver( + *object, JS_FUNCTION_TYPE, JSFunction::kSize)); } diff --git a/deps/v8/src/factory.h b/deps/v8/src/factory.h index a69b05b38f..71ae750b38 100644 --- a/deps/v8/src/factory.h +++ b/deps/v8/src/factory.h @@ -219,9 +219,9 @@ class Factory { Handle<Map> GetSlowElementsMap(Handle<Map> map); - Handle<Map> GetExternalArrayElementsMap(Handle<Map> map, - ExternalArrayType array_type, - bool safe_to_add_transition); + Handle<Map> GetElementsTransitionMap(Handle<Map> map, + ElementsKind elements_kind, + bool safe_to_add_transition); Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array); @@ -260,8 +260,9 @@ class Factory { Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype); - // Change the type of the argument into a regular JS object and reinitialize. - void BecomeJSObject(Handle<JSProxy> object); + // Change the type of the argument into a JS object/function and reinitialize. + void BecomeJSObject(Handle<JSReceiver> object); + void BecomeJSFunction(Handle<JSReceiver> object); Handle<JSFunction> NewFunction(Handle<String> name, Handle<Object> prototype); diff --git a/deps/v8/src/flags.cc b/deps/v8/src/flags.cc index c20f5ee05d..ab5b57cedc 100644 --- a/deps/v8/src/flags.cc +++ b/deps/v8/src/flags.cc @@ -31,7 +31,7 @@ #include "v8.h" #include "platform.h" -#include "smart-pointer.h" +#include "smart-array-pointer.h" #include "string-stream.h" @@ -193,7 +193,7 @@ static const char* Type2String(Flag::FlagType type) { } -static SmartPointer<const char> ToString(Flag* flag) { +static SmartArrayPointer<const char> ToString(Flag* flag) { HeapStringAllocator string_allocator; StringStream buffer(&string_allocator); switch (flag->type()) { @@ -528,7 +528,7 @@ void FlagList::PrintHelp() { printf("Options:\n"); for (size_t i = 0; i < num_flags; ++i) { Flag* f = &flags[i]; - SmartPointer<const char> value = ToString(f); + SmartArrayPointer<const char> value = ToString(f); printf(" --%s (%s)\n type: %s default: %s\n", f->name(), f->comment(), Type2String(f->type()), *value); } diff --git a/deps/v8/src/frames.h b/deps/v8/src/frames.h index 4f94ebc7d1..fed11c4faf 100644 --- a/deps/v8/src/frames.h +++ b/deps/v8/src/frames.h @@ -579,6 +579,7 @@ class ArgumentsAdaptorFrame: public JavaScriptFrame { virtual void Print(StringStream* accumulator, PrintMode mode, int index) const; + protected: explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator) : JavaScriptFrame(iterator) { } diff --git a/deps/v8/src/full-codegen.cc b/deps/v8/src/full-codegen.cc index 53ace82fe7..8073874132 100644 --- a/deps/v8/src/full-codegen.cc +++ b/deps/v8/src/full-codegen.cc @@ -286,11 +286,13 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) { } unsigned table_offset = cgen.EmitStackCheckTable(); - Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); + Code::Flags flags = Code::ComputeFlags(Code::FUNCTION); Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); code->set_optimizable(info->IsOptimizable()); cgen.PopulateDeoptimizationData(code); code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); + code->set_has_debug_break_slots( + info->isolate()->debugger()->IsDebuggerActive()); code->set_allow_osr_at_loop_nesting_level(0); code->set_stack_check_table_offset(table_offset); CodeGenerator::PrintCode(code, info); diff --git a/deps/v8/src/gdb-jit.cc b/deps/v8/src/gdb-jit.cc index 4d57e25460..68cb0533b8 100644 --- a/deps/v8/src/gdb-jit.cc +++ b/deps/v8/src/gdb-jit.cc @@ -993,7 +993,7 @@ class CodeDescription BASE_EMBEDDED { } #endif - SmartPointer<char> GetFilename() { + SmartArrayPointer<char> GetFilename() { return String::cast(script_->name())->ToCString(); } @@ -1991,7 +1991,7 @@ void GDBJITInterface::AddCode(Handle<String> name, GetScriptLineNumber(script, 0); if (!name.is_null()) { - SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); + SmartArrayPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); } else { AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); diff --git a/deps/v8/src/handles.cc b/deps/v8/src/handles.cc index 8c6439b227..35c363c10c 100644 --- a/deps/v8/src/handles.cc +++ b/deps/v8/src/handles.cc @@ -921,16 +921,13 @@ bool CompileLazyShared(Handle<SharedFunctionInfo> shared, } -static bool CompileLazyFunction(Handle<JSFunction> function, - ClearExceptionFlag flag, - InLoopFlag in_loop_flag) { +bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) { bool result = true; if (function->shared()->is_compiled()) { function->ReplaceCode(function->shared()->code()); function->shared()->set_code_age(0); } else { CompilationInfo info(function); - if (in_loop_flag == IN_LOOP) info.MarkAsInLoop(); result = CompileLazyHelper(&info, flag); ASSERT(!result || function->is_compiled()); } @@ -938,18 +935,6 @@ static bool CompileLazyFunction(Handle<JSFunction> function, } -bool CompileLazy(Handle<JSFunction> function, - ClearExceptionFlag flag) { - return CompileLazyFunction(function, flag, NOT_IN_LOOP); -} - - -bool CompileLazyInLoop(Handle<JSFunction> function, - ClearExceptionFlag flag) { - return CompileLazyFunction(function, flag, IN_LOOP); -} - - bool CompileOptimized(Handle<JSFunction> function, int osr_ast_id, ClearExceptionFlag flag) { diff --git a/deps/v8/src/handles.h b/deps/v8/src/handles.h index 9bb3b1f1d5..7eaf4de927 100644 --- a/deps/v8/src/handles.h +++ b/deps/v8/src/handles.h @@ -363,8 +363,6 @@ bool CompileLazyShared(Handle<SharedFunctionInfo> shared, bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag); -bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag flag); - bool CompileOptimized(Handle<JSFunction> function, int osr_ast_id, ClearExceptionFlag flag); diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc index 0ca138f337..d0185930b7 100644 --- a/deps/v8/src/heap.cc +++ b/deps/v8/src/heap.cc @@ -1627,7 +1627,7 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type, int instance_size) { map->set_unused_property_fields(0); map->set_bit_field(0); map->set_bit_field2(1 << Map::kIsExtensible); - map->set_elements_kind(JSObject::FAST_ELEMENTS); + map->set_elements_kind(FAST_ELEMENTS); // If the map object is aligned fill the padding area with Smi 0 objects. if (Map::kPadStart < Map::kSize) { @@ -3415,11 +3415,36 @@ MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { map->set_prototype(prototype); // Allocate the proxy object. - Object* result; + JSProxy* result; MaybeObject* maybe_result = Allocate(map, NEW_SPACE); - if (!maybe_result->ToObject(&result)) return maybe_result; - JSProxy::cast(result)->set_handler(handler); - JSProxy::cast(result)->set_padding(Smi::FromInt(0)); + if (!maybe_result->To<JSProxy>(&result)) return maybe_result; + result->InitializeBody(map->instance_size(), Smi::FromInt(0)); + result->set_handler(handler); + return result; +} + + +MaybeObject* Heap::AllocateJSFunctionProxy(Object* handler, + Object* call_trap, + Object* construct_trap, + Object* prototype) { + // Allocate map. + // TODO(rossberg): Once we optimize proxies, think about a scheme to share + // maps. Will probably depend on the identity of the handler object, too. + Map* map; + MaybeObject* maybe_map_obj = + AllocateMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize); + if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj; + map->set_prototype(prototype); + + // Allocate the proxy object. + JSFunctionProxy* result; + MaybeObject* maybe_result = Allocate(map, NEW_SPACE); + if (!maybe_result->To<JSFunctionProxy>(&result)) return maybe_result; + result->InitializeBody(map->instance_size(), Smi::FromInt(0)); + result->set_handler(handler); + result->set_call_trap(call_trap); + result->set_construct_trap(construct_trap); return result; } @@ -3564,16 +3589,19 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) { } -MaybeObject* Heap::ReinitializeJSProxyAsJSObject(JSProxy* object) { +MaybeObject* Heap::ReinitializeJSReceiver( + JSReceiver* object, InstanceType type, int size) { + ASSERT(type >= FIRST_JS_RECEIVER_TYPE); + // Allocate fresh map. // TODO(rossberg): Once we optimize proxies, cache these maps. Map* map; - MaybeObject* maybe_map_obj = - AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); + MaybeObject* maybe_map_obj = AllocateMap(type, size); if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj; - // Check that the receiver has the same size as a fresh object. - ASSERT(map->instance_size() == object->map()->instance_size()); + // Check that the receiver has at least the size of the fresh object. + int size_difference = object->map()->instance_size() - map->instance_size(); + ASSERT(size_difference >= 0); map->set_prototype(object->map()->prototype()); @@ -3590,6 +3618,28 @@ MaybeObject* Heap::ReinitializeJSProxyAsJSObject(JSProxy* object) { // Reinitialize the object from the constructor map. InitializeJSObjectFromMap(JSObject::cast(object), FixedArray::cast(properties), map); + + // Functions require some minimal initialization. + if (type == JS_FUNCTION_TYPE) { + String* name; + MaybeObject* maybe_name = LookupAsciiSymbol("<freezing call trap>"); + if (!maybe_name->To<String>(&name)) return maybe_name; + SharedFunctionInfo* shared; + MaybeObject* maybe_shared = AllocateSharedFunctionInfo(name); + if (!maybe_shared->To<SharedFunctionInfo>(&shared)) return maybe_shared; + JSFunction* func; + MaybeObject* maybe_func = + InitializeFunction(JSFunction::cast(object), shared, the_hole_value()); + if (!maybe_func->To<JSFunction>(&func)) return maybe_func; + func->set_context(isolate()->context()->global_context()); + } + + // Put in filler if the new object is smaller than the old. + if (size_difference > 0) { + CreateFillerObjectAt( + object->address() + map->instance_size(), size_difference); + } + return object; } diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h index cc689df17b..d81ff6cad5 100644 --- a/deps/v8/src/heap.h +++ b/deps/v8/src/heap.h @@ -440,17 +440,25 @@ class Heap { // Please note this does not perform a garbage collection. MUST_USE_RESULT MaybeObject* AllocateFunctionPrototype(JSFunction* function); - // Allocates a Harmony Proxy. + // Allocates a Harmony proxy or function proxy. // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation // failed. // Please note this does not perform a garbage collection. MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler, Object* prototype); - // Reinitialize a JSProxy into an (empty) JSObject. The receiver - // must have the same size as an empty object. The object is reinitialized - // and behaves as an object that has been freshly allocated. - MUST_USE_RESULT MaybeObject* ReinitializeJSProxyAsJSObject(JSProxy* object); + MUST_USE_RESULT MaybeObject* AllocateJSFunctionProxy(Object* handler, + Object* call_trap, + Object* construct_trap, + Object* prototype); + + // Reinitialize a JSReceiver into an (empty) JS object of respective type and + // size, but keeping the original prototype. The receiver must have at least + // the size of the new object. The object is reinitialized and behaves as an + // object that has been freshly allocated. + MUST_USE_RESULT MaybeObject* ReinitializeJSReceiver(JSReceiver* object, + InstanceType type, + int size); // Reinitialize an JSGlobalProxy based on a constructor. The object // must have the same size as objects allocated using the diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc index 14e1bc8a46..5630ce3913 100644 --- a/deps/v8/src/hydrogen-instructions.cc +++ b/deps/v8/src/hydrogen-instructions.cc @@ -1133,7 +1133,7 @@ void HDeoptimize::PrintDataTo(StringStream* stream) { void HEnterInlined::PrintDataTo(StringStream* stream) { - SmartPointer<char> name = function()->debug_name()->ToCString(); + SmartArrayPointer<char> name = function()->debug_name()->ToCString(); stream->Add("%s, id=%d", *name, function()->id()); } @@ -1307,6 +1307,12 @@ void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { left()->PrintNameTo(stream); stream->Add(" "); right()->PrintNameTo(stream); + HControlInstruction::PrintDataTo(stream); +} + + +void HGoto::PrintDataTo(StringStream* stream) { + stream->Add("B%d", SuccessorAt(0)->block_id()); } @@ -1454,37 +1460,37 @@ void HLoadKeyedSpecializedArrayElement::PrintDataTo( external_pointer()->PrintNameTo(stream); stream->Add("."); switch (elements_kind()) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: stream->Add("byte"); break; - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: stream->Add("u_byte"); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: stream->Add("short"); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: stream->Add("u_short"); break; - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: stream->Add("int"); break; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: stream->Add("u_int"); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: stream->Add("float"); break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: stream->Add("double"); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: stream->Add("pixel"); break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -1549,37 +1555,37 @@ void HStoreKeyedSpecializedArrayElement::PrintDataTo( external_pointer()->PrintNameTo(stream); stream->Add("."); switch (elements_kind()) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: stream->Add("byte"); break; - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: stream->Add("u_byte"); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: stream->Add("short"); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: stream->Add("u_short"); break; - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: stream->Add("int"); break; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: stream->Add("u_int"); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: stream->Add("float"); break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: stream->Add("double"); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: stream->Add("pixel"); break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h index 3ccf302e40..1bc28ba82d 100644 --- a/deps/v8/src/hydrogen-instructions.h +++ b/deps/v8/src/hydrogen-instructions.h @@ -915,6 +915,8 @@ class HGoto: public HTemplateControlInstruction<1, 0> { return Representation::None(); } + virtual void PrintDataTo(StringStream* stream); + DECLARE_CONCRETE_INSTRUCTION(Goto) }; @@ -2209,6 +2211,13 @@ class HPhi: public HValue { is_convertible_to_integer_ = b; } + bool AllOperandsConvertibleToInteger() { + for (int i = 0; i < OperandCount(); ++i) { + if (!OperandAt(i)->IsConvertibleToInteger()) return false; + } + return true; + } + protected: virtual void DeleteFromGraph(); virtual void InternalSetOperandAt(int index, HValue* value) { @@ -3555,12 +3564,12 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { public: HLoadKeyedSpecializedArrayElement(HValue* external_elements, HValue* key, - JSObject::ElementsKind elements_kind) + ElementsKind elements_kind) : elements_kind_(elements_kind) { SetOperandAt(0, external_elements); SetOperandAt(1, key); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || - elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || + elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { set_representation(Representation::Double()); } else { set_representation(Representation::Integer32()); @@ -3583,7 +3592,7 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { HValue* external_pointer() { return OperandAt(0); } HValue* key() { return OperandAt(1); } - JSObject::ElementsKind elements_kind() const { return elements_kind_; } + ElementsKind elements_kind() const { return elements_kind_; } DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement) @@ -3596,7 +3605,7 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { } private: - JSObject::ElementsKind elements_kind_; + ElementsKind elements_kind_; }; @@ -3776,7 +3785,7 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { HStoreKeyedSpecializedArrayElement(HValue* external_elements, HValue* key, HValue* val, - JSObject::ElementsKind elements_kind) + ElementsKind elements_kind) : elements_kind_(elements_kind) { SetFlag(kChangesSpecializedArrayElements); SetOperandAt(0, external_elements); @@ -3791,8 +3800,8 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { return Representation::External(); } else { bool float_or_double_elements = - elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS || - elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS; + elements_kind() == EXTERNAL_FLOAT_ELEMENTS || + elements_kind() == EXTERNAL_DOUBLE_ELEMENTS; if (index == 2 && float_or_double_elements) { return Representation::Double(); } else { @@ -3804,12 +3813,12 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { HValue* external_pointer() { return OperandAt(0); } HValue* key() { return OperandAt(1); } HValue* value() { return OperandAt(2); } - JSObject::ElementsKind elements_kind() const { return elements_kind_; } + ElementsKind elements_kind() const { return elements_kind_; } DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement) private: - JSObject::ElementsKind elements_kind_; + ElementsKind elements_kind_; }; diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc index ab25299b78..cca168a96b 100644 --- a/deps/v8/src/hydrogen.cc +++ b/deps/v8/src/hydrogen.cc @@ -220,6 +220,17 @@ bool HBasicBlock::Dominates(HBasicBlock* other) const { } +int HBasicBlock::LoopNestingDepth() const { + const HBasicBlock* current = this; + int result = (current->IsLoopHeader()) ? 1 : 0; + while (current->parent_loop_header() != NULL) { + current = current->parent_loop_header(); + result++; + } + return result; +} + + void HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) { ASSERT(IsLoopHeader()); @@ -638,8 +649,7 @@ Handle<Code> HGraph::Compile(CompilationInfo* info) { PrintF("Crankshaft Compiler - "); } CodeGenerator::MakeCodePrologue(info); - Code::Flags flags = - Code::ComputeFlags(Code::OPTIMIZED_FUNCTION, NOT_IN_LOOP); + Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&assembler, flags, info); generator.FinishCode(code); @@ -1638,18 +1648,20 @@ Representation HInferRepresentation::TryChange(HValue* value) { int non_tagged_count = double_count + int32_count; // If a non-loop phi has tagged uses, don't convert it to untagged. - if (value->IsPhi() && !value->block()->IsLoopHeader()) { - if (tagged_count > 0) return Representation::None(); + if (value->IsPhi() && !value->block()->IsLoopHeader() && tagged_count > 0) { + return Representation::None(); } - if (non_tagged_count >= tagged_count) { - if (int32_count > 0) { - if (!value->IsPhi() || value->IsConvertibleToInteger()) { - return Representation::Integer32(); - } - } - if (double_count > 0) return Representation::Double(); + // Prefer unboxing over boxing, the latter is more expensive. + if (tagged_count > non_tagged_count) Representation::None(); + + // Prefer Integer32 over Double, if possible. + if (int32_count > 0 && value->IsConvertibleToInteger()) { + return Representation::Integer32(); } + + if (double_count > 0) return Representation::Double(); + return Representation::None(); } @@ -1690,40 +1702,25 @@ void HInferRepresentation::Analyze() { } } - // (3) Sum up the non-phi use counts of all connected phis. Don't include - // the non-phi uses of the phi itself. + // (3) Use the phi reachability information from step 2 to + // (a) sum up the non-phi use counts of all connected phis. + // (b) push information about values which can't be converted to integer + // without deoptimization through the phi use-def chains, avoiding + // unnecessary deoptimizations later. for (int i = 0; i < phi_count; ++i) { HPhi* phi = phi_list->at(i); + bool cti = phi->AllOperandsConvertibleToInteger(); for (BitVector::Iterator it(connected_phis.at(i)); !it.Done(); it.Advance()) { int index = it.Current(); - if (index != i) { - HPhi* it_use = phi_list->at(it.Current()); - phi->AddNonPhiUsesFrom(it_use); - } - } - } - - // (4) Compute phis that definitely can't be converted to integer - // without deoptimization and mark them to avoid unnecessary deoptimization. - change = true; - while (change) { - change = false; - for (int i = 0; i < phi_count; ++i) { - HPhi* phi = phi_list->at(i); - for (int j = 0; j < phi->OperandCount(); ++j) { - if (phi->IsConvertibleToInteger() && - !phi->OperandAt(j)->IsConvertibleToInteger()) { - phi->set_is_convertible_to_integer(false); - change = true; - break; - } - } + HPhi* it_use = phi_list->at(it.Current()); + if (index != i) phi->AddNonPhiUsesFrom(it_use); // Don't count twice! + if (!cti) it_use->set_is_convertible_to_integer(false); } } - + // Initialize work list for (int i = 0; i < graph_->blocks()->length(); ++i) { HBasicBlock* block = graph_->blocks()->at(i); const ZoneList<HPhi*>* phis = block->phis(); @@ -1738,6 +1735,7 @@ void HInferRepresentation::Analyze() { } } + // Do a fixed point iteration, trying to improve representations while (!worklist_.is_empty()) { HValue* current = worklist_.RemoveLast(); in_worklist_.Remove(current->id()); @@ -2203,7 +2201,8 @@ void TestContext::BuildBranch(HValue* value) { void HGraphBuilder::Bailout(const char* reason) { if (FLAG_trace_bailout) { - SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + SmartArrayPointer<char> name( + info()->shared_info()->DebugName()->ToCString()); PrintF("Bailout in HGraphBuilder: @\"%s\": %s\n", *name, reason); } SetStackOverflow(); @@ -3904,35 +3903,35 @@ HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( HValue* external_elements, HValue* checked_key, HValue* val, - JSObject::ElementsKind elements_kind, + ElementsKind elements_kind, bool is_store) { if (is_store) { ASSERT(val != NULL); switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: { + case EXTERNAL_PIXEL_ELEMENTS: { HClampToUint8* clamp = new(zone()) HClampToUint8(val); AddInstruction(clamp); val = clamp; break; } - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: { HToInt32* floor_val = new(zone()) HToInt32(val); AddInstruction(floor_val); val = floor_val; break; } - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -4016,7 +4015,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, SmallMapList* maps = prop->GetReceiverTypes(); bool todo_external_array = false; - static const int kNumElementTypes = JSObject::kElementsKindCount; + static const int kNumElementTypes = kElementsKindCount; bool type_todo[kNumElementTypes]; for (int i = 0; i < kNumElementTypes; ++i) { type_todo[i] = false; @@ -4026,7 +4025,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, ASSERT(maps->at(i)->IsMap()); type_todo[maps->at(i)->elements_kind()] = true; if (maps->at(i)->elements_kind() - >= JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { + >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { todo_external_array = true; } } @@ -4041,16 +4040,16 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, HInstruction* checked_key = NULL; // FAST_ELEMENTS is assumed to be the first case. - STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); + STATIC_ASSERT(FAST_ELEMENTS == 0); - for (JSObject::ElementsKind elements_kind = JSObject::FAST_ELEMENTS; - elements_kind <= JSObject::LAST_ELEMENTS_KIND; - elements_kind = JSObject::ElementsKind(elements_kind + 1)) { + for (ElementsKind elements_kind = FAST_ELEMENTS; + elements_kind <= LAST_ELEMENTS_KIND; + elements_kind = ElementsKind(elements_kind + 1)) { // After having handled FAST_ELEMENTS and DICTIONARY_ELEMENTS, we // need to add some code that's executed for all external array cases. - STATIC_ASSERT(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == - JSObject::LAST_ELEMENTS_KIND); - if (elements_kind == JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND + STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == + LAST_ELEMENTS_KIND); + if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && todo_external_array) { HInstruction* length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); @@ -4069,11 +4068,11 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, set_current_block(if_true); HInstruction* access; - if (elements_kind == JSObject::FAST_ELEMENTS || - elements_kind == JSObject::FAST_DOUBLE_ELEMENTS) { + if (elements_kind == FAST_ELEMENTS || + elements_kind == FAST_DOUBLE_ELEMENTS) { bool fast_double_elements = - elements_kind == JSObject::FAST_DOUBLE_ELEMENTS; - if (is_store && elements_kind == JSObject::FAST_ELEMENTS) { + elements_kind == FAST_DOUBLE_ELEMENTS; + if (is_store && elements_kind == FAST_ELEMENTS) { AddInstruction(new(zone()) HCheckMap( elements, isolate()->factory()->fixed_array_map(), elements_kind_branch)); @@ -4138,7 +4137,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, new(zone()) HLoadKeyedFastElement(elements, checked_key)); } } - } else if (elements_kind == JSObject::DICTIONARY_ELEMENTS) { + } else if (elements_kind == DICTIONARY_ELEMENTS) { if (is_store) { access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); } else { @@ -4433,8 +4432,10 @@ void HGraphBuilder::TraceInline(Handle<JSFunction> target, Handle<JSFunction> caller, const char* reason) { if (FLAG_trace_inlining) { - SmartPointer<char> target_name = target->shared()->DebugName()->ToCString(); - SmartPointer<char> caller_name = caller->shared()->DebugName()->ToCString(); + SmartArrayPointer<char> target_name = + target->shared()->DebugName()->ToCString(); + SmartArrayPointer<char> caller_name = + caller->shared()->DebugName()->ToCString(); if (reason == NULL) { PrintF("Inlined %s called from %s.\n", *target_name, *caller_name); } else { @@ -5913,7 +5914,9 @@ void HGraphBuilder::GenerateIsFunction(CallRuntime* call) { CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); HValue* value = Pop(); HHasInstanceTypeAndBranch* result = - new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE); + new(zone()) HHasInstanceTypeAndBranch(value, + JS_FUNCTION_TYPE, + JS_FUNCTION_PROXY_TYPE); return ast_context()->ReturnControl(result, call->id()); } @@ -6567,6 +6570,8 @@ void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { PrintBlockProperty("dominator", current->dominator()->block_id()); } + PrintIntProperty("loop_depth", current->LoopNestingDepth()); + if (chunk != NULL) { int first_index = current->first_instruction_index(); int last_index = current->last_instruction_index(); diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h index 614991f7c2..03fbc73220 100644 --- a/deps/v8/src/hydrogen.h +++ b/deps/v8/src/hydrogen.h @@ -102,6 +102,7 @@ class HBasicBlock: public ZoneObject { void RemovePhi(HPhi* phi); void AddInstruction(HInstruction* instr); bool Dominates(HBasicBlock* other) const; + int LoopNestingDepth() const; void SetInitialEnvironment(HEnvironment* env); void ClearEnvironment() { last_environment_ = NULL; } @@ -935,7 +936,7 @@ class HGraphBuilder: public AstVisitor { HValue* external_elements, HValue* checked_key, HValue* val, - JSObject::ElementsKind elements_kind, + ElementsKind elements_kind, bool is_store); HInstruction* BuildMonomorphicElementAccess(HValue* object, diff --git a/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h index c186094b39..4698e3ed1b 100644 --- a/deps/v8/src/ia32/assembler-ia32.h +++ b/deps/v8/src/ia32/assembler-ia32.h @@ -465,6 +465,7 @@ class CpuFeatures : public AllStatic { // Enable a specified feature within a scope. class Scope BASE_EMBEDDED { #ifdef DEBUG + public: explicit Scope(CpuFeature f) { uint64_t mask = static_cast<uint64_t>(1) << f; @@ -484,10 +485,12 @@ class CpuFeatures : public AllStatic { isolate_->set_enabled_cpu_features(old_enabled_); } } + private: Isolate* isolate_; uint64_t old_enabled_; #else + public: explicit Scope(CpuFeature f) {} #endif diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc index 845a073c40..310ea3d123 100644 --- a/deps/v8/src/ia32/builtins-ia32.cc +++ b/deps/v8/src/ia32/builtins-ia32.cc @@ -590,16 +590,17 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { // 2. Get the function to call (passed as receiver) from the stack, check // if it is a function. - Label non_function; + Label slow, non_function; // 1 ~ return address. __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize)); __ JumpIfSmi(edi, &non_function); __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); - __ j(not_equal, &non_function); + __ j(not_equal, &slow); // 3a. Patch the first argument if necessary when calling a function. Label shift_arguments; + __ Set(edx, Immediate(0)); // indicate regular JS_FUNCTION { Label convert_to_object, use_global_receiver, patch_receiver; // Change context eagerly in case we need the global receiver. __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); @@ -637,6 +638,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ push(ebx); __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); __ mov(ebx, eax); + __ Set(edx, Immediate(0)); // restore __ pop(eax); __ SmiUntag(eax); @@ -661,14 +663,19 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ jmp(&shift_arguments); } - // 3b. Patch the first argument when calling a non-function. The + // 3b. Check for function proxy. + __ bind(&slow); + __ Set(edx, Immediate(1)); // indicate function proxy + __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); + __ j(equal, &shift_arguments); + __ bind(&non_function); + __ Set(edx, Immediate(2)); // indicate non-function + + // 3c. Patch the first argument when calling a non-function. The // CALL_NON_FUNCTION builtin expects the non-function callee as // receiver, so overwrite the first argument which will ultimately // become the receiver. - __ bind(&non_function); __ mov(Operand(esp, eax, times_4, 0), edi); - // Clear edi to indicate a non-function being called. - __ Set(edi, Immediate(0)); // 4. Shift arguments and return address one slot down on the stack // (overwriting the original receiver). Adjust argument count to make @@ -685,13 +692,26 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ dec(eax); // One fewer argument (first argument is new receiver). } - // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. - { Label function; - __ test(edi, Operand(edi)); - __ j(not_zero, &function); + // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, + // or a function proxy via CALL_FUNCTION_PROXY. + { Label function, non_proxy; + __ test(edx, Operand(edx)); + __ j(zero, &function); __ Set(ebx, Immediate(0)); - __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); __ SetCallKind(ecx, CALL_AS_METHOD); + __ cmp(Operand(edx), Immediate(1)); + __ j(not_equal, &non_proxy); + + __ pop(edx); // return address + __ push(edi); // re-add proxy object as additional argument + __ push(edx); + __ inc(eax); + __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); + __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), + RelocInfo::CODE_TARGET); + + __ bind(&non_proxy); + __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), RelocInfo::CODE_TARGET); __ bind(&function); @@ -717,13 +737,17 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { void Builtins::Generate_FunctionApply(MacroAssembler* masm) { + static const int kArgumentsOffset = 2 * kPointerSize; + static const int kReceiverOffset = 3 * kPointerSize; + static const int kFunctionOffset = 4 * kPointerSize; + __ EnterInternalFrame(); - __ push(Operand(ebp, 4 * kPointerSize)); // push this - __ push(Operand(ebp, 2 * kPointerSize)); // push arguments + __ push(Operand(ebp, kFunctionOffset)); // push this + __ push(Operand(ebp, kArgumentsOffset)); // push arguments __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); - // Check the stack for overflow. We are not trying need to catch + // Check the stack for overflow. We are not trying to catch // interruptions (e.g. debug break and preemption) here, so the "real stack // limit" is checked. Label okay; @@ -756,16 +780,21 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ push(eax); // limit __ push(Immediate(0)); // index - // Change context eagerly to get the right global object if - // necessary. - __ mov(edi, Operand(ebp, 4 * kPointerSize)); + // Get the receiver. + __ mov(ebx, Operand(ebp, kReceiverOffset)); + + // Check that the function is a JS function (otherwise it must be a proxy). + Label push_receiver; + __ mov(edi, Operand(ebp, kFunctionOffset)); + __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); + __ j(not_equal, &push_receiver); + + // Change context eagerly to get the right global object if necessary. __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); // Compute the receiver. - Label call_to_object, use_global_receiver, push_receiver; - __ mov(ebx, Operand(ebp, 3 * kPointerSize)); - // Do not transform the receiver for strict mode functions. + Label call_to_object, use_global_receiver; __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), 1 << SharedFunctionInfo::kStrictModeBitWithinByte); @@ -814,7 +843,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ mov(eax, Operand(ebp, kIndexOffset)); __ jmp(&entry); __ bind(&loop); - __ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments + __ mov(edx, Operand(ebp, kArgumentsOffset)); // load arguments // Use inline caching to speed up access to arguments. Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize(); @@ -837,14 +866,30 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ j(not_equal, &loop); // Invoke the function. + Label call_proxy; ParameterCount actual(eax); __ SmiUntag(eax); - __ mov(edi, Operand(ebp, 4 * kPointerSize)); + __ mov(edi, Operand(ebp, kFunctionOffset)); + __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); + __ j(not_equal, &call_proxy); __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); __ LeaveInternalFrame(); __ ret(3 * kPointerSize); // remove this, receiver, and arguments + + // Invoke the function proxy. + __ bind(&call_proxy); + __ push(edi); // add function proxy as last argument + __ inc(eax); + __ Set(ebx, Immediate(0)); + __ SetCallKind(ecx, CALL_AS_METHOD); + __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); + __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), + RelocInfo::CODE_TARGET); + + __ LeaveInternalFrame(); + __ ret(3 * kPointerSize); // remove this, receiver, and arguments } diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc index f3eb09fa51..1009aaf573 100644 --- a/deps/v8/src/ia32/code-stubs-ia32.cc +++ b/deps/v8/src/ia32/code-stubs-ia32.cc @@ -3551,7 +3551,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { // stack overflow (on the backtrack stack) was detected in RegExp code but // haven't created the exception yet. Handle that in the runtime system. // TODO(592): Rerunning the RegExp to get the stack overflow exception. - ExternalReference pending_exception(Isolate::k_pending_exception_address, + ExternalReference pending_exception(Isolate::kPendingExceptionAddress, masm->isolate()); __ mov(edx, Operand::StaticVariable(ExternalReference::the_hole_value_location( @@ -4199,7 +4199,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) { void CallFunctionStub::Generate(MacroAssembler* masm) { - Label slow; + Label slow, non_function; // The receiver might implicitly be the global object. This is // indicated by passing the hole as the receiver to the call @@ -4224,7 +4224,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); // Check that the function really is a JavaScript function. - __ JumpIfSmi(edi, &slow); + __ JumpIfSmi(edi, &non_function); // Goto slow case if we do not have a function. __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); __ j(not_equal, &slow); @@ -4251,15 +4251,32 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); + // Check for function proxy. + __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); + __ j(not_equal, &non_function); + __ pop(ecx); + __ push(edi); // put proxy as additional argument under return address + __ push(ecx); + __ Set(eax, Immediate(argc_ + 1)); + __ Set(ebx, Immediate(0)); + __ SetCallKind(ecx, CALL_AS_FUNCTION); + __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); + { + Handle<Code> adaptor = + masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); + __ jmp(adaptor, RelocInfo::CODE_TARGET); + } + // CALL_NON_FUNCTION expects the non-function callee as receiver (instead // of the original receiver from the call site). + __ bind(&non_function); __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); __ Set(eax, Immediate(argc_)); __ Set(ebx, Immediate(0)); + __ SetCallKind(ecx, CALL_AS_METHOD); __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); Handle<Code> adaptor = masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); - __ SetCallKind(ecx, CALL_AS_METHOD); __ jmp(adaptor, RelocInfo::CODE_TARGET); } @@ -4341,7 +4358,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ j(zero, &failure_returned); ExternalReference pending_exception_address( - Isolate::k_pending_exception_address, masm->isolate()); + Isolate::kPendingExceptionAddress, masm->isolate()); // Check that there is no pending exception, otherwise we // should have returned some failure value. @@ -4482,11 +4499,11 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { __ push(ebx); // Save copies of the top frame descriptor on the stack. - ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate()); + ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, masm->isolate()); __ push(Operand::StaticVariable(c_entry_fp)); // If this is the outermost JS call, set js_entry_sp value. - ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, + ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, masm->isolate()); __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); __ j(not_equal, ¬_outermost_js, Label::kNear); @@ -4503,7 +4520,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Caught exception: Store result (exception) in the pending // exception field in the JSEnv and return a failure sentinel. - ExternalReference pending_exception(Isolate::k_pending_exception_address, + ExternalReference pending_exception(Isolate::kPendingExceptionAddress, masm->isolate()); __ mov(Operand::StaticVariable(pending_exception), eax); __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); @@ -4554,7 +4571,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Restore the top frame descriptor from the stack. __ pop(Operand::StaticVariable(ExternalReference( - Isolate::k_c_entry_fp_address, + Isolate::kCEntryFPAddress, masm->isolate()))); // Restore callee-saved registers (C calling conventions). diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc index 59f7b9c7b3..81c9ccb128 100644 --- a/deps/v8/src/ia32/full-codegen-ia32.cc +++ b/deps/v8/src/ia32/full-codegen-ia32.cc @@ -2013,9 +2013,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr, } // Record source position of the IC call. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ call(ic, mode, expr->id()); RecordJSReturnSite(expr); // Restore context register. @@ -2047,9 +2046,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, } // Record source position of the IC call. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( - arg_count, in_loop); + Handle<Code> ic = + isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. __ call(ic, RelocInfo::CODE_TARGET, expr->id()); RecordJSReturnSite(expr); @@ -2071,8 +2069,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, flags); + CallFunctionStub stub(arg_count, flags); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -2166,8 +2163,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { } // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); + CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -3582,10 +3578,9 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { if (expr->is_jsruntime()) { // Call the JS runtime function via a call IC. __ Set(ecx, Immediate(expr->name())); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; RelocInfo::Mode mode = RelocInfo::CODE_TARGET; - Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( - arg_count, in_loop, mode); + Handle<Code> ic = + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ call(ic, mode, expr->id()); // Restore context register. __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); diff --git a/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc index 7d3ead2eac..9b5cc56401 100644 --- a/deps/v8/src/ia32/ic-ia32.cc +++ b/deps/v8/src/ia32/ic-ia32.cc @@ -144,7 +144,7 @@ static void GenerateDictionaryLoad(MacroAssembler* masm, StringDictionary::kElementsStartIndex * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), - Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); + Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); __ j(not_zero, miss_label); // Get the value at the masked, scaled index. @@ -198,9 +198,9 @@ static void GenerateDictionaryStore(MacroAssembler* masm, StringDictionary::kHeaderSize + StringDictionary::kElementsStartIndex * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask - = (PropertyDetails::TypeField::mask() | - PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; + const int kTypeAndReadOnlyMask = + (PropertyDetails::TypeField::kMask | + PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), Immediate(kTypeAndReadOnlyMask)); __ j(not_zero, miss_label); @@ -832,7 +832,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, // Probe the stub cache. Code::Flags flags = Code::ComputeFlags(kind, - NOT_IN_LOOP, MONOMORPHIC, extra_ic_state, NORMAL, @@ -1237,9 +1236,7 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // ----------------------------------- // Probe the stub cache. - Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, - NOT_IN_LOOP, - MONOMORPHIC); + Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC); Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, eax, ecx, ebx, edx); @@ -1339,10 +1336,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm, // -- esp[0] : return address // ----------------------------------- - Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, - NOT_IN_LOOP, - MONOMORPHIC, - strict_mode); + Code::Flags flags = + Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode); Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, no_reg); diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc index 31e9dd82e2..4e3ea98161 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.cc +++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc @@ -88,7 +88,8 @@ void LCodeGen::FinishCode(Handle<Code> code) { void LCodeGen::Abort(const char* format, ...) { if (FLAG_trace_bailout) { - SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + SmartArrayPointer<char> name( + info()->shared_info()->DebugName()->ToCString()); PrintF("Aborting LCodeGen in @\"%s\": ", *name); va_list arguments; va_start(arguments, format); @@ -2219,11 +2220,11 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) { __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); __ and_(temp, Map::kElementsKindMask); __ shr(temp, Map::kElementsKindShift); - __ cmp(temp, JSObject::FAST_ELEMENTS); + __ cmp(temp, FAST_ELEMENTS); __ j(equal, &ok, Label::kNear); - __ cmp(temp, JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); + __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); __ j(less, &fail, Label::kNear); - __ cmp(temp, JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); + __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); __ j(less_equal, &ok, Label::kNear); __ bind(&fail); __ Abort("Check for fast or external elements failed."); @@ -2264,7 +2265,7 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { // Load the result. __ mov(result, BuildFastArrayOperand(instr->elements(), instr->key(), - JSObject::FAST_ELEMENTS, + FAST_ELEMENTS, FixedArray::kHeaderSize - kHeapObjectTag)); // Check for the hole value. @@ -2284,14 +2285,14 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( sizeof(kHoleNanLower32); Operand hole_check_operand = BuildFastArrayOperand( instr->elements(), instr->key(), - JSObject::FAST_DOUBLE_ELEMENTS, + FAST_DOUBLE_ELEMENTS, offset); __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); DeoptimizeIf(equal, instr->environment()); } Operand double_load_operand = BuildFastArrayOperand( - instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, + instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, FixedDoubleArray::kHeaderSize - kHeapObjectTag); __ movdbl(result, double_load_operand); } @@ -2300,7 +2301,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( Operand LCodeGen::BuildFastArrayOperand( LOperand* elements_pointer, LOperand* key, - JSObject::ElementsKind elements_kind, + ElementsKind elements_kind, uint32_t offset) { Register elements_pointer_reg = ToRegister(elements_pointer); int shift_size = ElementsKindToShiftSize(elements_kind); @@ -2320,35 +2321,35 @@ Operand LCodeGen::BuildFastArrayOperand( void LCodeGen::DoLoadKeyedSpecializedArrayElement( LLoadKeyedSpecializedArrayElement* instr) { - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildFastArrayOperand(instr->external_pointer(), instr->key(), elements_kind, 0)); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { XMMRegister result(ToDoubleRegister(instr->result())); __ movss(result, operand); __ cvtss2sd(result, result); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ movdbl(ToDoubleRegister(instr->result()), operand); } else { Register result(ToRegister(instr->result())); switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ movsx_b(result, operand); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movzx_b(result, operand); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: __ movsx_w(result, operand); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzx_w(result, operand); break; - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: __ mov(result, operand); break; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ mov(result, operand); __ test(result, Operand(result)); // TODO(danno): we could be more clever here, perhaps having a special @@ -2356,12 +2357,12 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( // happens, and generate code that returns a double rather than int. DeoptimizeIf(negative, instr->environment()); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -2980,8 +2981,8 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) { ASSERT(ToRegister(instr->result()).is(eax)); int arity = instr->arity(); - Handle<Code> ic = isolate()->stub_cache()-> - ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); + Handle<Code> ic = + isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -2993,7 +2994,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { int arity = instr->arity(); RelocInfo::Mode mode = RelocInfo::CODE_TARGET; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); + isolate()->stub_cache()->ComputeCallInitialize(arity, mode); __ mov(ecx, instr->name()); CallCode(ic, mode, instr); } @@ -3004,7 +3005,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { ASSERT(ToRegister(instr->result()).is(eax)); int arity = instr->arity(); - CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); + CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); __ Drop(1); } @@ -3017,7 +3018,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { int arity = instr->arity(); RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); + isolate()->stub_cache()->ComputeCallInitialize(arity, mode); __ mov(ecx, instr->name()); CallCode(ic, mode, instr); } @@ -3103,36 +3104,36 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { void LCodeGen::DoStoreKeyedSpecializedArrayElement( LStoreKeyedSpecializedArrayElement* instr) { - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildFastArrayOperand(instr->external_pointer(), instr->key(), elements_kind, 0)); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); __ movss(operand, xmm0); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ movdbl(operand, ToDoubleRegister(instr->value())); } else { Register value = ToRegister(instr->value()); switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ mov_b(operand, value); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ mov_w(operand, value); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ mov(operand, value); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3186,7 +3187,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( __ bind(&have_value); Operand double_store_operand = BuildFastArrayOperand( - instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, + instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, FixedDoubleArray::kHeaderSize - kHeapObjectTag); __ movdbl(double_store_operand, value); } diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.h b/deps/v8/src/ia32/lithium-codegen-ia32.h index d26f245553..6156327420 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.h +++ b/deps/v8/src/ia32/lithium-codegen-ia32.h @@ -224,7 +224,7 @@ class LCodeGen BASE_EMBEDDED { int ToInteger32(LConstantOperand* op) const; Operand BuildFastArrayOperand(LOperand* elements_pointer, LOperand* key, - JSObject::ElementsKind elements_kind, + ElementsKind elements_kind, uint32_t offset); // Specific math operations - used from DoUnaryMathOperation. diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc index 34c5beb38d..3dc220d3d9 100644 --- a/deps/v8/src/ia32/lithium-ia32.cc +++ b/deps/v8/src/ia32/lithium-ia32.cc @@ -315,13 +315,13 @@ void LCallKeyed::PrintDataTo(StringStream* stream) { void LCallNamed::PrintDataTo(StringStream* stream) { - SmartPointer<char> name_string = name()->ToCString(); + SmartArrayPointer<char> name_string = name()->ToCString(); stream->Add("%s #%d / ", *name_string, arity()); } void LCallGlobal::PrintDataTo(StringStream* stream) { - SmartPointer<char> name_string = name()->ToCString(); + SmartArrayPointer<char> name_string = name()->ToCString(); stream->Add("%s #%d / ", *name_string, arity()); } @@ -540,7 +540,8 @@ LChunk* LChunkBuilder::Build() { void LChunkBuilder::Abort(const char* format, ...) { if (FLAG_trace_bailout) { - SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + SmartArrayPointer<char> name( + info()->shared_info()->DebugName()->ToCString()); PrintF("Aborting LChunk building in @\"%s\": ", *name); va_list arguments; va_start(arguments, format); @@ -1902,15 +1903,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( HLoadKeyedSpecializedArrayElement* instr) { - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); Representation representation(instr->representation()); ASSERT( (representation.IsInteger32() && - (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (representation.IsDouble() && - ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); + ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); @@ -1920,7 +1921,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* load_instr = DefineAsRegister(result); // An unsigned int array load might overflow and cause a deopt, make sure it // has an environment. - return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) + return (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) ? AssignEnvironment(load_instr) : load_instr; } @@ -1972,23 +1973,23 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( HStoreKeyedSpecializedArrayElement* instr) { Representation representation(instr->value()->representation()); - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); ASSERT( (representation.IsInteger32() && - (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (representation.IsDouble() && - ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); + ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); LOperand* val = NULL; - if (elements_kind == JSObject::EXTERNAL_BYTE_ELEMENTS || - elements_kind == JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS || - elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind == EXTERNAL_BYTE_ELEMENTS || + elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS || + elements_kind == EXTERNAL_PIXEL_ELEMENTS) { // We need a byte register in this case for the value. val = UseFixed(instr->value(), eax); } else { diff --git a/deps/v8/src/ia32/lithium-ia32.h b/deps/v8/src/ia32/lithium-ia32.h index e752b714e4..038049ca06 100644 --- a/deps/v8/src/ia32/lithium-ia32.h +++ b/deps/v8/src/ia32/lithium-ia32.h @@ -1184,7 +1184,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } - JSObject::ElementsKind elements_kind() const { + ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } }; @@ -1699,7 +1699,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - JSObject::ElementsKind elements_kind() const { + ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } }; diff --git a/deps/v8/src/ia32/macro-assembler-ia32.cc b/deps/v8/src/ia32/macro-assembler-ia32.cc index 6d3ce2bcd9..837112a55c 100644 --- a/deps/v8/src/ia32/macro-assembler-ia32.cc +++ b/deps/v8/src/ia32/macro-assembler-ia32.cc @@ -287,7 +287,7 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { void MacroAssembler::CheckFastElements(Register map, Label* fail, Label::Distance distance) { - STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); + STATIC_ASSERT(FAST_ELEMENTS == 0); cmpb(FieldOperand(map, Map::kBitField2Offset), Map::kMaximumBitField2FastElementValue); j(above, fail, distance); @@ -437,9 +437,9 @@ void MacroAssembler::EnterExitFramePrologue() { push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. // Save the frame pointer and the context in top. - ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, + ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); - ExternalReference context_address(Isolate::k_context_address, + ExternalReference context_address(Isolate::kContextAddress, isolate()); mov(Operand::StaticVariable(c_entry_fp_address), ebp); mov(Operand::StaticVariable(context_address), esi); @@ -518,14 +518,14 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles) { void MacroAssembler::LeaveExitFrameEpilogue() { // Restore current context from top and clear it in debug mode. - ExternalReference context_address(Isolate::k_context_address, isolate()); + ExternalReference context_address(Isolate::kContextAddress, isolate()); mov(esi, Operand::StaticVariable(context_address)); #ifdef DEBUG mov(Operand::StaticVariable(context_address), Immediate(0)); #endif // Clear the top frame. - ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, + ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); } @@ -567,10 +567,10 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, push(Immediate(Smi::FromInt(0))); // No context. } // Save the current handler as the next handler. - push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, + push(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress, isolate()))); // Link this handler as the new current one. - mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, + mov(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress, isolate())), esp); } @@ -578,7 +578,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, void MacroAssembler::PopTryHandler() { STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); - pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, + pop(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress, isolate()))); add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); } @@ -598,7 +598,7 @@ void MacroAssembler::Throw(Register value) { } // Drop the sp to the top of the handler. - ExternalReference handler_address(Isolate::k_handler_address, + ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); mov(esp, Operand::StaticVariable(handler_address)); @@ -637,7 +637,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, } // Drop sp to the top stack handler. - ExternalReference handler_address(Isolate::k_handler_address, + ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); mov(esp, Operand::StaticVariable(handler_address)); @@ -660,13 +660,13 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, if (type == OUT_OF_MEMORY) { // Set external caught exception to false. ExternalReference external_caught( - Isolate::k_external_caught_exception_address, + Isolate::kExternalCaughtExceptionAddress, isolate()); mov(eax, false); mov(Operand::StaticVariable(external_caught), eax); // Set pending exception and eax to out of memory exception. - ExternalReference pending_exception(Isolate::k_pending_exception_address, + ExternalReference pending_exception(Isolate::kPendingExceptionAddress, isolate()); mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); mov(Operand::StaticVariable(pending_exception), eax); @@ -840,7 +840,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss, NumberDictionary::kElementsStartOffset + 2 * kPointerSize; ASSERT_EQ(NORMAL, 0); test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), - Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); + Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); j(not_zero, miss); // Get the value at the masked, scaled index. diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc index 621a9bbfa2..ab62764e64 100644 --- a/deps/v8/src/ia32/stub-cache-ia32.cc +++ b/deps/v8/src/ia32/stub-cache-ia32.cc @@ -2679,7 +2679,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { // -- esp[0] : return address // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; MaybeObject* maybe_stub = KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode(); @@ -3140,7 +3140,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { // -- esp[0] : return address // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(edx, @@ -3385,7 +3385,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- eax : key // -- edx : receiver @@ -3407,29 +3407,29 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); // ebx: base pointer of external storage switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ SmiUntag(eax); // Untag the index. __ movsx_b(eax, Operand(ebx, eax, times_1, 0)); break; - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: __ SmiUntag(eax); // Untag the index. __ movzx_b(eax, Operand(ebx, eax, times_1, 0)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: __ movsx_w(eax, Operand(ebx, eax, times_1, 0)); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzx_w(eax, Operand(ebx, eax, times_1, 0)); break; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: __ mov(ecx, Operand(ebx, eax, times_2, 0)); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: __ fld_s(Operand(ebx, eax, times_2, 0)); break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: __ fld_d(Operand(ebx, eax, times_4, 0)); break; default: @@ -3442,17 +3442,17 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // For floating-point array type: // FP(0): value - if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS || - elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { + if (elements_kind == EXTERNAL_INT_ELEMENTS || + elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { // For the Int and UnsignedInt array types, we need to see whether // the value can be represented in a Smi. If not, we need to convert // it to a HeapNumber. Label box_int; - if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { + if (elements_kind == EXTERNAL_INT_ELEMENTS) { __ cmp(ecx, 0xC0000000); __ j(sign, &box_int); } else { - ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); + ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); // The test is different for unsigned int values. Since we need // the value to be in the range of a positive smi, we can't // handle either of the top two bits being set in the value. @@ -3468,12 +3468,12 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // Allocate a HeapNumber for the int and perform int-to-double // conversion. - if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { + if (elements_kind == EXTERNAL_INT_ELEMENTS) { __ push(ecx); __ fild_s(Operand(esp, 0)); __ pop(ecx); } else { - ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); + ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); // Need to zero-extend the value. // There's no fild variant for unsigned values, so zero-extend // to a 64-bit int manually. @@ -3489,8 +3489,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(eax, ecx); __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ ret(0); - } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || - elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || + elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); @@ -3540,7 +3540,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- eax : key // -- edx : receiver @@ -3566,7 +3566,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // edx: receiver // ecx: key // edi: elements array - if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { __ JumpIfNotSmi(eax, &slow); } else { __ JumpIfNotSmi(eax, &check_heap_number); @@ -3578,33 +3578,33 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); // edi: base pointer of external storage switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: __ ClampUint8(ebx); __ SmiUntag(ecx); __ mov_b(Operand(edi, ecx, times_1, 0), ebx); break; - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ SmiUntag(ecx); __ mov_b(Operand(edi, ecx, times_1, 0), ebx); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ mov_w(Operand(edi, ecx, times_1, 0), ebx); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ mov(Operand(edi, ecx, times_2, 0), ebx); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: // Need to perform int-to-float conversion. __ push(ebx); __ fild_s(Operand(esp, 0)); __ pop(ebx); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ fstp_s(Operand(edi, ecx, times_2, 0)); - } else { // elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS. + } else { // elements_kind == EXTERNAL_DOUBLE_ELEMENTS. __ fstp_d(Operand(edi, ecx, times_4, 0)); } break; @@ -3615,7 +3615,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ ret(0); // Return the original value. // TODO(danno): handle heap number -> pixel array conversion - if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { __ bind(&check_heap_number); // eax: value // edx: receiver @@ -3630,11 +3630,11 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // reproducible behavior, convert these to zero. __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); // edi: base pointer of external storage - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ fstp_s(Operand(edi, ecx, times_2, 0)); __ ret(0); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ fstp_d(Operand(edi, ecx, times_4, 0)); __ ret(0); @@ -3647,23 +3647,23 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // (code-stubs-ia32.cc) is roughly what is needed here though the // conversion failure case does not need to be handled. if (CpuFeatures::IsSupported(SSE2)) { - if (elements_kind != JSObject::EXTERNAL_INT_ELEMENTS && - elements_kind != JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { + if (elements_kind != EXTERNAL_INT_ELEMENTS && + elements_kind != EXTERNAL_UNSIGNED_INT_ELEMENTS) { ASSERT(CpuFeatures::IsSupported(SSE2)); CpuFeatures::Scope scope(SSE2); __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset)); // ecx: untagged integer value switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: __ ClampUint8(ebx); // Fall through. - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ SmiUntag(ecx); __ mov_b(Operand(edi, ecx, times_1, 0), ebx); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ mov_w(Operand(edi, ecx, times_1, 0), ebx); break; default: diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc index 0d0b93570b..0f76a9a06c 100644 --- a/deps/v8/src/ic.cc +++ b/deps/v8/src/ic.cc @@ -61,8 +61,7 @@ static char TransitionMarkFromState(IC::State state) { void IC::TraceIC(const char* type, Handle<Object> name, State old_state, - Code* new_target, - const char* extra_info) { + Code* new_target) { if (FLAG_trace_ic) { State new_state = StateFrom(new_target, HEAP->undefined_value(), @@ -94,10 +93,9 @@ void IC::TraceIC(const char* type, } else { PrintF("<unknown>"); } - PrintF(" (%c->%c)%s", + PrintF(" (%c->%c)", TransitionMarkFromState(old_state), - TransitionMarkFromState(new_state), - extra_info); + TransitionMarkFromState(new_state)); name->Print(); PrintF("]\n"); } @@ -326,7 +324,6 @@ void CallICBase::Clear(Address address, Code* target) { Code* code = Isolate::Current()->stub_cache()->FindCallInitialize( target->arguments_count(), - target->ic_in_loop(), contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, target->kind()); SetTargetAtAddress(address, code); @@ -604,13 +601,11 @@ MaybeObject* CallICBase::ComputeMonomorphicStub( Handle<Object> object, Handle<String> name) { int argc = target()->arguments_count(); - InLoopFlag in_loop = target()->ic_in_loop(); MaybeObject* maybe_code = NULL; switch (lookup->type()) { case FIELD: { int index = lookup->GetFieldIndex(); maybe_code = isolate()->stub_cache()->ComputeCallField(argc, - in_loop, kind_, extra_ic_state, *name, @@ -626,7 +621,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub( JSFunction* function = lookup->GetConstantFunction(); maybe_code = isolate()->stub_cache()->ComputeCallConstant(argc, - in_loop, kind_, extra_ic_state, *name, @@ -646,7 +640,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub( if (!cell->value()->IsJSFunction()) return NULL; JSFunction* function = JSFunction::cast(cell->value()); maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, - in_loop, kind_, extra_ic_state, *name, @@ -661,7 +654,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub( // applicable. if (lookup->holder() != *receiver) return NULL; maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, - in_loop, kind_, extra_ic_state, *name, @@ -706,7 +698,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup, // Compute the number of arguments. int argc = target()->arguments_count(); - InLoopFlag in_loop = target()->ic_in_loop(); MaybeObject* maybe_code = NULL; bool had_proto_failure = false; if (state == UNINITIALIZED) { @@ -715,7 +706,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup, // setting the monomorphic state. maybe_code = isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, - in_loop, kind_, extra_ic_state); } else if (state == MONOMORPHIC) { @@ -739,7 +729,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup, } else { maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(argc, - in_loop, kind_, extra_ic_state); } @@ -776,7 +765,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup, #ifdef DEBUG if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", - name, state, target(), in_loop ? " (in-loop)" : ""); + name, state, target()); #endif } @@ -797,31 +786,28 @@ MaybeObject* KeyedCallIC::LoadFunction(State state, if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { int argc = target()->arguments_count(); - InLoopFlag in_loop = target()->ic_in_loop(); Heap* heap = Handle<HeapObject>::cast(object)->GetHeap(); Map* map = heap->non_strict_arguments_elements_map(); if (object->IsJSObject() && Handle<JSObject>::cast(object)->elements()->map() == map) { MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( - argc, in_loop, Code::KEYED_CALL_IC); + argc, Code::KEYED_CALL_IC); Object* code; if (maybe_code->ToObject(&code)) { set_target(Code::cast(code)); #ifdef DEBUG - TraceIC( - "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); + TraceIC("KeyedCallIC", key, state, target()); #endif } } else if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) { MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( - argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState); + argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); Object* code; if (maybe_code->ToObject(&code)) { set_target(Code::cast(code)); #ifdef DEBUG - TraceIC( - "KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : ""); + TraceIC("KeyedCallIC", key, state, target()); #endif } } @@ -1093,7 +1079,7 @@ void LoadIC::UpdateCaches(LookupResult* lookup, MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck( bool is_js_array, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { return KeyedLoadElementStub(elements_kind).TryGetCode(); } @@ -1650,7 +1636,6 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver, PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache(); Code::Flags flags = Code::ComputeFlags(this->kind(), - NOT_IN_LOOP, MEGAMORPHIC, strict_mode); Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags); @@ -1721,7 +1706,7 @@ MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver, MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck( bool is_js_array, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { return KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); } @@ -1905,16 +1890,11 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup, // static JSFunction* CompileFunction(Isolate* isolate, - JSFunction* function, - InLoopFlag in_loop) { + JSFunction* function) { // Compile now with optimization. HandleScope scope(isolate); Handle<JSFunction> function_handle(function, isolate); - if (in_loop == IN_LOOP) { - CompileLazyInLoop(function_handle, CLEAR_EXCEPTION); - } else { - CompileLazy(function_handle, CLEAR_EXCEPTION); - } + CompileLazy(function_handle, CLEAR_EXCEPTION); return *function_handle; } @@ -1943,9 +1923,7 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { return result; } - return CompileFunction(isolate, - JSFunction::cast(result), - ic.target()->ic_in_loop()); + return CompileFunction(isolate, JSFunction::cast(result)); } @@ -1964,9 +1942,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { return result; } - return CompileFunction(isolate, - JSFunction::cast(result), - ic.target()->ic_in_loop()); + return CompileFunction(isolate, JSFunction::cast(result)); } diff --git a/deps/v8/src/ic.h b/deps/v8/src/ic.h index 2236ba37b6..ece5be9f05 100644 --- a/deps/v8/src/ic.h +++ b/deps/v8/src/ic.h @@ -149,8 +149,7 @@ class IC { void TraceIC(const char* type, Handle<Object> name, State old_state, - Code* new_target, - const char* extra_info = ""); + Code* new_target); #endif Failure* TypeError(const char* type, @@ -348,7 +347,7 @@ class KeyedIC: public IC { virtual MaybeObject* GetElementStubWithoutMapCheck( bool is_js_array, - JSObject::ElementsKind elements_kind) = 0; + ElementsKind elements_kind) = 0; protected: virtual Code* string_stub() { @@ -415,7 +414,7 @@ class KeyedLoadIC: public KeyedIC { virtual MaybeObject* GetElementStubWithoutMapCheck( bool is_js_array, - JSObject::ElementsKind elements_kind); + ElementsKind elements_kind); protected: virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } @@ -566,7 +565,7 @@ class KeyedStoreIC: public KeyedIC { virtual MaybeObject* GetElementStubWithoutMapCheck( bool is_js_array, - JSObject::ElementsKind elements_kind); + ElementsKind elements_kind); protected: virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } diff --git a/deps/v8/src/inspector.h b/deps/v8/src/inspector.h index f8b3042861..e328bcdfa5 100644 --- a/deps/v8/src/inspector.h +++ b/deps/v8/src/inspector.h @@ -41,7 +41,6 @@ namespace internal { class Inspector { public: - static void DumpObjectType(FILE* out, Object *obj, bool print_more); static void DumpObjectType(FILE* out, Object *obj) { DumpObjectType(out, obj, false); @@ -59,4 +58,3 @@ class Inspector { #endif // INSPECTOR #endif // V8_INSPECTOR_H_ - diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc index afb9624875..fd0f673e7e 100644 --- a/deps/v8/src/isolate.cc +++ b/deps/v8/src/isolate.cc @@ -1414,7 +1414,7 @@ Isolate::Isolate() TRACE_ISOLATE(constructor); memset(isolate_addresses_, 0, - sizeof(isolate_addresses_[0]) * (k_isolate_address_count + 1)); + sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1)); heap_.isolate_ = this; zone_.isolate_ = this; @@ -1686,9 +1686,10 @@ bool Isolate::Init(Deserializer* des) { // ensuring that Isolate::Current() == this. heap_.SetStackLimits(); -#define C(name) isolate_addresses_[Isolate::k_##name] = \ - reinterpret_cast<Address>(name()); - ISOLATE_ADDRESS_LIST(C) +#define ASSIGN_ELEMENT(CamelName, hacker_name) \ + isolate_addresses_[Isolate::k##CamelName##Address] = \ + reinterpret_cast<Address>(hacker_name##_address()); + FOR_EACH_ISOLATE_ADDRESS_NAME(ASSIGN_ELEMENT) #undef C string_tracker_ = new StringTracker(); diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h index 7c690d26ba..2582da644a 100644 --- a/deps/v8/src/isolate.h +++ b/deps/v8/src/isolate.h @@ -119,13 +119,13 @@ typedef ZoneList<Handle<Object> > ZoneObjectList; #define RETURN_IF_EMPTY_HANDLE(isolate, call) \ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception()) -#define ISOLATE_ADDRESS_LIST(C) \ - C(handler_address) \ - C(c_entry_fp_address) \ - C(context_address) \ - C(pending_exception_address) \ - C(external_caught_exception_address) \ - C(js_entry_sp_address) +#define FOR_EACH_ISOLATE_ADDRESS_NAME(C) \ + C(Handler, handler) \ + C(CEntryFP, c_entry_fp) \ + C(Context, context) \ + C(PendingException, pending_exception) \ + C(ExternalCaughtException, external_caught_exception) \ + C(JSEntrySP, js_entry_sp) // Platform-independent, reliable thread identifier. @@ -423,10 +423,10 @@ class Isolate { enum AddressId { -#define C(name) k_##name, - ISOLATE_ADDRESS_LIST(C) +#define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address, + FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM) #undef C - k_isolate_address_count + kIsolateAddressCount }; // Returns the PerIsolateThreadData for the current thread (or NULL if one is @@ -1097,7 +1097,7 @@ class Isolate { StringStream* incomplete_message_; // The preallocated memory thread singleton. PreallocatedMemoryThread* preallocated_memory_thread_; - Address isolate_addresses_[k_isolate_address_count + 1]; // NOLINT + Address isolate_addresses_[kIsolateAddressCount + 1]; // NOLINT NoAllocationStringAllocator* preallocated_message_space_; Bootstrapper* bootstrapper_; diff --git a/deps/v8/src/json.js b/deps/v8/src/json.js index a491bcc151..deba126212 100644 --- a/deps/v8/src/json.js +++ b/deps/v8/src/json.js @@ -54,7 +54,7 @@ function Revive(holder, name, reviver) { function JSONParse(text, reviver) { var unfiltered = %ParseJson(TO_STRING_INLINE(text)); - if (IS_FUNCTION(reviver)) { + if (IS_SPEC_FUNCTION(reviver)) { return Revive({'': unfiltered}, '', reviver); } else { return unfiltered; @@ -143,11 +143,11 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) { var value = holder[key]; if (IS_SPEC_OBJECT(value)) { var toJSON = value.toJSON; - if (IS_FUNCTION(toJSON)) { + if (IS_SPEC_FUNCTION(toJSON)) { value = %_CallFunction(value, key, toJSON); } } - if (IS_FUNCTION(replacer)) { + if (IS_SPEC_FUNCTION(replacer)) { value = %_CallFunction(holder, key, value, replacer); } if (IS_STRING(value)) { @@ -273,7 +273,7 @@ function BasicSerializeObject(value, stack, builder) { function BasicJSONSerialize(key, value, stack, builder) { if (IS_SPEC_OBJECT(value)) { var toJSON = value.toJSON; - if (IS_FUNCTION(toJSON)) { + if (IS_SPEC_FUNCTION(toJSON)) { value = %_CallFunction(value, ToString(key), toJSON); } } diff --git a/deps/v8/src/jsregexp.h b/deps/v8/src/jsregexp.h index 3bd5e00893..54297a49ab 100644 --- a/deps/v8/src/jsregexp.h +++ b/deps/v8/src/jsregexp.h @@ -255,6 +255,7 @@ class SetRelation BASE_EMBEDDED { return (bits_ == (kInFirst | kInSecond | kInBoth)); } int value() { return bits_; } + private: int bits_; }; @@ -404,6 +405,7 @@ class DispatchTable : public ZoneObject { template <typename Callback> void ForEach(Callback* callback) { return tree()->ForEach(callback); } + private: // There can't be a static empty set since it allocates its // successors in a zone and caches them. @@ -793,6 +795,7 @@ class ActionNode: public SeqRegExpNode { virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } virtual ActionNode* Clone() { return new ActionNode(*this); } virtual int ComputeFirstCharacterSet(int budget); + private: union { struct { @@ -861,6 +864,7 @@ class TextNode: public SeqRegExpNode { } void CalculateOffsets(); virtual int ComputeFirstCharacterSet(int budget); + private: enum TextEmitPassType { NON_ASCII_MATCH, // Check for characters that can't match. @@ -925,6 +929,7 @@ class AssertionNode: public SeqRegExpNode { virtual AssertionNode* Clone() { return new AssertionNode(*this); } AssertionNodeType type() { return type_; } void set_type(AssertionNodeType type) { type_ = type; } + private: AssertionNode(AssertionNodeType t, RegExpNode* on_success) : SeqRegExpNode(on_success), type_(t) { } @@ -955,6 +960,7 @@ class BackReferenceNode: public SeqRegExpNode { } virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); } virtual int ComputeFirstCharacterSet(int budget); + private: int start_reg_; int end_reg_; @@ -1301,6 +1307,7 @@ class Trace { } void InvalidateCurrentCharacter(); void AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler); + private: int FindAffectedRegisters(OutSet* affected_registers); void PerformDeferredActions(RegExpMacroAssembler* macro, @@ -1402,6 +1409,7 @@ FOR_EACH_NODE_TYPE(DECLARE_VISIT) void fail(const char* error_message) { error_message_ = error_message; } + private: bool ignore_case_; bool is_ascii_; diff --git a/deps/v8/src/list-inl.h b/deps/v8/src/list-inl.h index 8ef7514f4f..80bccc9bc3 100644 --- a/deps/v8/src/list-inl.h +++ b/deps/v8/src/list-inl.h @@ -207,6 +207,35 @@ void List<T, P>::Initialize(int capacity) { } +template <typename T> +int SortedListBSearch( + const List<T>& list, T elem, int (*cmp)(const T* x, const T* y)) { + int low = 0; + int high = list.length() - 1; + while (low <= high) { + int mid = (low + high) / 2; + T mid_elem = list[mid]; + + if (mid_elem > elem) { + high = mid - 1; + continue; + } + if (mid_elem < elem) { + low = mid + 1; + continue; + } + // Found the elememt. + return mid; + } + return -1; +} + + +template <typename T> +int SortedListBSearch(const List<T>& list, T elem) { + return SortedListBSearch<T>(list, elem, PointerValueCompare<T>); +} + } } // namespace v8::internal #endif // V8_LIST_INL_H_ diff --git a/deps/v8/src/list.h b/deps/v8/src/list.h index ca2b7bce22..055870904e 100644 --- a/deps/v8/src/list.h +++ b/deps/v8/src/list.h @@ -49,7 +49,6 @@ namespace internal { template <typename T, class P> class List { public: - List() { Initialize(0); } INLINE(explicit List(int capacity)) { Initialize(capacity); } INLINE(~List()) { DeleteData(data_); } @@ -169,6 +168,15 @@ class Code; typedef List<Map*> MapList; typedef List<Code*> CodeList; +// Perform binary search for an element in an already sorted +// list. Returns the index of the element of -1 if it was not found. +template <typename T> +int SortedListBSearch( + const List<T>& list, T elem, int (*cmp)(const T* x, const T* y)); +template <typename T> +int SortedListBSearch(const List<T>& list, T elem); + } } // namespace v8::internal + #endif // V8_LIST_H_ diff --git a/deps/v8/src/lithium.cc b/deps/v8/src/lithium.cc index 64ef469b33..5410f6f058 100644 --- a/deps/v8/src/lithium.cc +++ b/deps/v8/src/lithium.cc @@ -166,25 +166,25 @@ void LPointerMap::PrintTo(StringStream* stream) { } -int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind) { +int ElementsKindToShiftSize(ElementsKind elements_kind) { switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: return 0; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: return 1; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: return 2; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: return 3; - case JSObject::FAST_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: return kPointerSizeLog2; } UNREACHABLE(); diff --git a/deps/v8/src/lithium.h b/deps/v8/src/lithium.h index 6010b777ed..20da21a63c 100644 --- a/deps/v8/src/lithium.h +++ b/deps/v8/src/lithium.h @@ -165,8 +165,7 @@ class LUnallocated: public LOperand { } Policy policy() const { return PolicyField::decode(value_); } void set_policy(Policy policy) { - value_ &= ~PolicyField::mask(); - value_ |= PolicyField::encode(policy); + value_ = PolicyField::update(value_, policy); } int fixed_index() const { return static_cast<int>(value_) >> kFixedIndexShift; @@ -177,8 +176,7 @@ class LUnallocated: public LOperand { } void set_virtual_register(unsigned id) { - value_ &= ~VirtualRegisterField::mask(); - value_ |= VirtualRegisterField::encode(id); + value_ = VirtualRegisterField::update(value_, id); } LUnallocated* CopyUnconstrained() { @@ -586,7 +584,7 @@ class DeepIterator BASE_EMBEDDED { }; -int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind); +int ElementsKindToShiftSize(ElementsKind elements_kind); } } // namespace v8::internal diff --git a/deps/v8/src/liveedit.cc b/deps/v8/src/liveedit.cc index 07c9fdde05..d44c2fc1cd 100644 --- a/deps/v8/src/liveedit.cc +++ b/deps/v8/src/liveedit.cc @@ -1450,7 +1450,7 @@ static bool FixTryCatchHandler(StackFrame* top_frame, StackFrame* bottom_frame) { Address* pointer_address = &Memory::Address_at(Isolate::Current()->get_address_from_id( - Isolate::k_handler_address)); + Isolate::kHandlerAddress)); while (*pointer_address < top_frame->sp()) { pointer_address = &Memory::Address_at(*pointer_address); diff --git a/deps/v8/src/liveobjectlist.cc b/deps/v8/src/liveobjectlist.cc index 451a28ab70..957c0515d6 100644 --- a/deps/v8/src/liveobjectlist.cc +++ b/deps/v8/src/liveobjectlist.cc @@ -184,7 +184,7 @@ bool IsOfType(LiveObjectType type, HeapObject *obj) { const AllocationSpace kInvalidSpace = static_cast<AllocationSpace>(-1); static AllocationSpace FindSpaceFor(String* space_str) { - SmartPointer<char> s = + SmartArrayPointer<char> s = space_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); const char* key_str = *s; @@ -236,7 +236,7 @@ static bool InSpace(AllocationSpace space, HeapObject *heap_obj) { static LiveObjectType FindTypeFor(String* type_str) { - SmartPointer<char> s = + SmartArrayPointer<char> s = type_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); #define CHECK_OBJECT_TYPE(type_, name) { \ @@ -503,10 +503,10 @@ static void GenerateObjectDesc(HeapObject* obj, // We'll only dump 80 of them after we compact them. const int kMaxCharToDump = 80; const int kMaxBufferSize = kMaxCharToDump * 2; - SmartPointer<char> str_sp = str->ToCString(DISALLOW_NULLS, - ROBUST_STRING_TRAVERSAL, - 0, - kMaxBufferSize); + SmartArrayPointer<char> str_sp = str->ToCString(DISALLOW_NULLS, + ROBUST_STRING_TRAVERSAL, + 0, + kMaxBufferSize); char* str_cstr = *str_sp; int length = CompactString(str_cstr); OS::SNPrintF(buffer_v, @@ -526,14 +526,14 @@ static void GenerateObjectDesc(HeapObject* obj, } String* name = sinfo->DebugName(); - SmartPointer<char> name_sp = + SmartArrayPointer<char> name_sp = name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); char* name_cstr = *name_sp; HeapStringAllocator string_allocator; StringStream stream(&string_allocator); sinfo->SourceCodePrint(&stream, 50); - SmartPointer<const char> source_sp = stream.ToCString(); + SmartArrayPointer<const char> source_sp = stream.ToCString(); const char* source_cstr = *source_sp; OS::SNPrintF(buffer_v, @@ -1656,7 +1656,7 @@ int LiveObjectList::GetObjId(Object* obj) { // Gets the obj id for the specified address if valid. Object* LiveObjectList::GetObjId(Handle<String> address) { - SmartPointer<char> addr_str = + SmartArrayPointer<char> addr_str = address->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); Isolate* isolate = Isolate::Current(); diff --git a/deps/v8/src/liveobjectlist.h b/deps/v8/src/liveobjectlist.h index 542482d9c5..65470d7ad9 100644 --- a/deps/v8/src/liveobjectlist.h +++ b/deps/v8/src/liveobjectlist.h @@ -114,7 +114,6 @@ class LiveObjectList { static Object* PrintObj(int obj_id); private: - struct Element { int id_; HeapObject* obj_; @@ -224,7 +223,6 @@ class LiveObjectList { // Helper class for updating the LiveObjectList HeapObject pointers. class UpdateLiveObjectListVisitor: public ObjectVisitor { public: - void VisitPointer(Object** p) { UpdatePointer(p); } void VisitPointers(Object** start, Object** end) { @@ -319,4 +317,3 @@ class LiveObjectList { } } // namespace v8::internal #endif // V8_LIVEOBJECTLIST_H_ - diff --git a/deps/v8/src/log-utils.cc b/deps/v8/src/log-utils.cc index 27e654d5e8..7bd7baa2d8 100644 --- a/deps/v8/src/log-utils.cc +++ b/deps/v8/src/log-utils.cc @@ -125,7 +125,7 @@ void Log::Initialize() { stream.Put(*p); } } - SmartPointer<const char> expanded = stream.ToCString(); + SmartArrayPointer<const char> expanded = stream.ToCString(); OpenFile(*expanded); } else { OpenFile(FLAG_logfile); diff --git a/deps/v8/src/log-utils.h b/deps/v8/src/log-utils.h index 2b20a01bbc..d0cb828983 100644 --- a/deps/v8/src/log-utils.h +++ b/deps/v8/src/log-utils.h @@ -141,7 +141,6 @@ class LogMessageBuilder BASE_EMBEDDED { void WriteToLogFile(); private: - Log* log_; ScopedLock sl; int pos_; diff --git a/deps/v8/src/log.cc b/deps/v8/src/log.cc index dedf7e90c5..3d66b5fb10 100644 --- a/deps/v8/src/log.cc +++ b/deps/v8/src/log.cc @@ -617,7 +617,7 @@ void Logger::ApiEvent(const char* format, ...) { void Logger::ApiNamedSecurityCheck(Object* key) { if (!log_->IsEnabled() || !FLAG_log_api) return; if (key->IsString()) { - SmartPointer<char> str = + SmartArrayPointer<char> str = String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); ApiEvent("api,check-security,\"%s\"\n", *str); } else if (key->IsUndefined()) { @@ -762,9 +762,9 @@ void Logger::ApiNamedPropertyAccess(const char* tag, ASSERT(name->IsString()); if (!log_->IsEnabled() || !FLAG_log_api) return; String* class_name_obj = holder->class_name(); - SmartPointer<char> class_name = + SmartArrayPointer<char> class_name = class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); - SmartPointer<char> property_name = + SmartArrayPointer<char> property_name = String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name); } @@ -774,7 +774,7 @@ void Logger::ApiIndexedPropertyAccess(const char* tag, uint32_t index) { if (!log_->IsEnabled() || !FLAG_log_api) return; String* class_name_obj = holder->class_name(); - SmartPointer<char> class_name = + SmartArrayPointer<char> class_name = class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index); } @@ -782,7 +782,7 @@ void Logger::ApiIndexedPropertyAccess(const char* tag, void Logger::ApiObjectAccess(const char* tag, JSObject* object) { if (!log_->IsEnabled() || !FLAG_log_api) return; String* class_name_obj = object->class_name(); - SmartPointer<char> class_name = + SmartArrayPointer<char> class_name = class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); ApiEvent("api,%s,\"%s\"\n", tag, *class_name); } @@ -836,7 +836,7 @@ void Logger::CallbackEventInternal(const char* prefix, const char* name, void Logger::CallbackEvent(String* name, Address entry_point) { if (!log_->IsEnabled() || !FLAG_log_code) return; - SmartPointer<char> str = + SmartArrayPointer<char> str = name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); CallbackEventInternal("", *str, entry_point); } @@ -844,7 +844,7 @@ void Logger::CallbackEvent(String* name, Address entry_point) { void Logger::GetterCallbackEvent(String* name, Address entry_point) { if (!log_->IsEnabled() || !FLAG_log_code) return; - SmartPointer<char> str = + SmartArrayPointer<char> str = name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); CallbackEventInternal("get ", *str, entry_point); } @@ -852,7 +852,7 @@ void Logger::GetterCallbackEvent(String* name, Address entry_point) { void Logger::SetterCallbackEvent(String* name, Address entry_point) { if (!log_->IsEnabled() || !FLAG_log_code) return; - SmartPointer<char> str = + SmartArrayPointer<char> str = name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); CallbackEventInternal("set ", *str, entry_point); } @@ -957,7 +957,7 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, return; LogMessageBuilder msg(this); - SmartPointer<char> str = + SmartArrayPointer<char> str = name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); msg.Append("%s,%s,", kLogEventsNames[CODE_CREATION_EVENT], @@ -998,9 +998,9 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, } if (!FLAG_log_code) return; LogMessageBuilder msg(this); - SmartPointer<char> name = + SmartArrayPointer<char> name = shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); - SmartPointer<char> sourcestr = + SmartArrayPointer<char> sourcestr = source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); msg.Append("%s,%s,", kLogEventsNames[CODE_CREATION_EVENT], @@ -1527,6 +1527,51 @@ void Logger::LogCodeObjects() { } +void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared, + Handle<Code> code) { + Handle<String> func_name(shared->DebugName()); + if (shared->script()->IsScript()) { + Handle<Script> script(Script::cast(shared->script())); + if (script->name()->IsString()) { + Handle<String> script_name(String::cast(script->name())); + int line_num = GetScriptLineNumber(script, shared->start_position()); + if (line_num > 0) { + PROFILE(ISOLATE, + CodeCreateEvent( + Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), + *code, *shared, + *script_name, line_num + 1)); + } else { + // Can't distinguish eval and script here, so always use Script. + PROFILE(ISOLATE, + CodeCreateEvent( + Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), + *code, *shared, *script_name)); + } + } else { + PROFILE(ISOLATE, + CodeCreateEvent( + Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), + *code, *shared, *func_name)); + } + } else if (shared->IsApiFunction()) { + // API function. + FunctionTemplateInfo* fun_data = shared->get_api_func_data(); + Object* raw_call_data = fun_data->call_code(); + if (!raw_call_data->IsUndefined()) { + CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); + Object* callback_obj = call_data->callback(); + Address entry_point = v8::ToCData<Address>(callback_obj); + PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point)); + } + } else { + PROFILE(ISOLATE, + CodeCreateEvent( + Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name)); + } +} + + void Logger::LogCompiledFunctions() { HandleScope scope; const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL); @@ -1540,48 +1585,7 @@ void Logger::LogCompiledFunctions() { if (*code_objects[i] == Isolate::Current()->builtins()->builtin( Builtins::kLazyCompile)) continue; - Handle<SharedFunctionInfo> shared = sfis[i]; - Handle<String> func_name(shared->DebugName()); - if (shared->script()->IsScript()) { - Handle<Script> script(Script::cast(shared->script())); - if (script->name()->IsString()) { - Handle<String> script_name(String::cast(script->name())); - int line_num = GetScriptLineNumber(script, shared->start_position()); - if (line_num > 0) { - PROFILE(ISOLATE, - CodeCreateEvent( - Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), - *code_objects[i], *shared, - *script_name, line_num + 1)); - } else { - // Can't distinguish eval and script here, so always use Script. - PROFILE(ISOLATE, - CodeCreateEvent( - Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), - *code_objects[i], *shared, *script_name)); - } - } else { - PROFILE(ISOLATE, - CodeCreateEvent( - Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), - *code_objects[i], *shared, *func_name)); - } - } else if (shared->IsApiFunction()) { - // API function. - FunctionTemplateInfo* fun_data = shared->get_api_func_data(); - Object* raw_call_data = fun_data->call_code(); - if (!raw_call_data->IsUndefined()) { - CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); - Object* callback_obj = call_data->callback(); - Address entry_point = v8::ToCData<Address>(callback_obj); - PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point)); - } - } else { - PROFILE(ISOLATE, - CodeCreateEvent( - Logger::LAZY_COMPILE_TAG, *code_objects[i], - *shared, *func_name)); - } + LogExistingFunction(sfis[i], code_objects[i]); } } diff --git a/deps/v8/src/log.h b/deps/v8/src/log.h index 02250595f8..fe19810a2c 100644 --- a/deps/v8/src/log.h +++ b/deps/v8/src/log.h @@ -281,6 +281,8 @@ class Logger { void ResumeProfiler(); bool IsProfilerPaused(); + void LogExistingFunction(Handle<SharedFunctionInfo> shared, + Handle<Code> code); // Logs all compiled functions found in the heap. void LogCompiledFunctions(); // Logs all accessor callbacks found in the heap. diff --git a/deps/v8/src/macros.py b/deps/v8/src/macros.py index e3d1e03871..7a493ca70f 100644 --- a/deps/v8/src/macros.py +++ b/deps/v8/src/macros.py @@ -116,9 +116,17 @@ macro FLOOR(arg) = $floor(arg); # Macro for ECMAScript 5 queries of the type: # "Type(O) is object." -# This is the same as being either a function or an object in V8 terminology. +# This is the same as being either a function or an object in V8 terminology +# (including proxies). # In addition, an undetectable object is also included by this. -macro IS_SPEC_OBJECT(arg) = (%_IsSpecObject(arg)); +macro IS_SPEC_OBJECT(arg) = (%_IsSpecObject(arg)); + +# Macro for ECMAScript 5 queries of the type: +# "IsCallable(O)" +# We assume here that this is the same as being either a function or a function +# proxy. That ignores host objects with [[Call]] methods, but in most situations +# we cannot handle those anyway. +macro IS_SPEC_FUNCTION(arg) = (%_ClassOf(arg) === 'Function'); # Inline macros. Use %IS_VAR to make sure arg is evaluated only once. macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg)); diff --git a/deps/v8/src/messages.cc b/deps/v8/src/messages.cc index 4cbf0af747..b6ad5ac352 100644 --- a/deps/v8/src/messages.cc +++ b/deps/v8/src/messages.cc @@ -41,13 +41,13 @@ namespace internal { // by default. void MessageHandler::DefaultMessageReport(const MessageLocation* loc, Handle<Object> message_obj) { - SmartPointer<char> str = GetLocalizedMessage(message_obj); + SmartArrayPointer<char> str = GetLocalizedMessage(message_obj); if (loc == NULL) { PrintF("%s\n", *str); } else { HandleScope scope; Handle<Object> data(loc->script()->name()); - SmartPointer<char> data_str; + SmartArrayPointer<char> data_str; if (data->IsString()) data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS); PrintF("%s:%i: %s\n", *data_str ? *data_str : "<unknown>", @@ -170,7 +170,8 @@ Handle<String> MessageHandler::GetMessage(Handle<Object> data) { } -SmartPointer<char> MessageHandler::GetLocalizedMessage(Handle<Object> data) { +SmartArrayPointer<char> MessageHandler::GetLocalizedMessage( + Handle<Object> data) { HandleScope scope; return GetMessage(data)->ToCString(DISALLOW_NULLS); } diff --git a/deps/v8/src/messages.h b/deps/v8/src/messages.h index fc2162ded0..358509ec3b 100644 --- a/deps/v8/src/messages.h +++ b/deps/v8/src/messages.h @@ -105,7 +105,7 @@ class MessageHandler { static void DefaultMessageReport(const MessageLocation* loc, Handle<Object> message_obj); static Handle<String> GetMessage(Handle<Object> data); - static SmartPointer<char> GetLocalizedMessage(Handle<Object> data); + static SmartArrayPointer<char> GetLocalizedMessage(Handle<Object> data); }; } } // namespace v8::internal diff --git a/deps/v8/src/messages.js b/deps/v8/src/messages.js index 3c85d9416a..a9993af229 100644 --- a/deps/v8/src/messages.js +++ b/deps/v8/src/messages.js @@ -185,6 +185,7 @@ function FormatMessage(message) { "define_disallowed", ["Cannot define property:", "%0", ", object is not extensible."], "non_extensible_proto", ["%0", " is not extensible"], "handler_non_object", ["Proxy.", "%0", " called with non-object as handler"], + "trap_function_expected", ["Proxy.", "%0", " called with non-function for ", "%1", " trap"], "handler_trap_missing", ["Proxy handler ", "%0", " has no '", "%1", "' trap"], "handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"], "handler_returned_false", ["Proxy handler ", "%0", " returned false for '", "%1", "' trap"], @@ -239,6 +240,8 @@ function FormatMessage(message) { "strict_poison_pill", ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"], "strict_caller", ["Illegal access to a strict mode caller function."], "unprotected_let", ["Illegal let declaration in unprotected statement context."], + "cant_prevent_ext_external_array_elements", ["Cannot prevent extension of an object with external array elements"], + "redef_external_array_element", ["Cannot redefine a property of an object with external array elements"], ]; var messages = { __proto__ : null }; var desc = new PropertyDescriptor(); diff --git a/deps/v8/src/mips/assembler-mips-inl.h b/deps/v8/src/mips/assembler-mips-inl.h index b5ffe7391b..c4c4fd2590 100644 --- a/deps/v8/src/mips/assembler-mips-inl.h +++ b/deps/v8/src/mips/assembler-mips-inl.h @@ -83,6 +83,14 @@ bool Operand::is_reg() const { // RelocInfo. void RelocInfo::apply(intptr_t delta) { + if (IsCodeTarget(rmode_)) { + uint32_t scope1 = (uint32_t) target_address() & ~kImm28Mask; + uint32_t scope2 = reinterpret_cast<uint32_t>(pc_) & ~kImm28Mask; + + if (scope1 != scope2) { + Assembler::JumpLabelToJumpRegister(pc_); + } + } if (IsInternalReference(rmode_)) { // Absolute code pointer inside code object moves with the code object. byte* p = reinterpret_cast<byte*>(pc_); @@ -218,8 +226,9 @@ bool RelocInfo::IsPatchedReturnSequence() { Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize); bool patched_return = ((instr0 & kOpcodeMask) == LUI && (instr1 & kOpcodeMask) == ORI && - (instr2 & kOpcodeMask) == SPECIAL && - (instr2 & kFunctionFieldMask) == JALR); + ((instr2 & kOpcodeMask) == JAL || + ((instr2 & kOpcodeMask) == SPECIAL && + (instr2 & kFunctionFieldMask) == JALR))); return patched_return; } diff --git a/deps/v8/src/mips/assembler-mips.cc b/deps/v8/src/mips/assembler-mips.cc index f30f38bb75..e01a0ca70b 100644 --- a/deps/v8/src/mips/assembler-mips.cc +++ b/deps/v8/src/mips/assembler-mips.cc @@ -172,7 +172,8 @@ Register ToRegister(int num) { // ----------------------------------------------------------------------------- // Implementation of RelocInfo. -const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; +const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | + 1 << RelocInfo::INTERNAL_REFERENCE; bool RelocInfo::IsCodedSpecially() { @@ -546,6 +547,19 @@ bool Assembler::IsJ(Instr instr) { } +bool Assembler::IsJal(Instr instr) { + return GetOpcodeField(instr) == JAL; +} + +bool Assembler::IsJr(Instr instr) { + return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR; +} + +bool Assembler::IsJalr(Instr instr) { + return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JALR; +} + + bool Assembler::IsLui(Instr instr) { uint32_t opcode = GetOpcodeField(instr); // Checks if the instruction is a load upper immediate. @@ -939,7 +953,7 @@ void Assembler::GenInstrImmediate(Opcode opcode, void Assembler::GenInstrJump(Opcode opcode, - uint32_t address) { + uint32_t address) { BlockTrampolinePoolScope block_trampoline_pool(this); ASSERT(is_uint26(address)); Instr instr = opcode | address; @@ -1112,7 +1126,12 @@ void Assembler::bne(Register rs, Register rt, int16_t offset) { void Assembler::j(int32_t target) { - ASSERT(is_uint28(target) && ((target & 3) == 0)); +#if DEBUG + // Get pc of delay slot. + uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); + bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; + ASSERT(in_range && ((target & 3) == 0)); +#endif GenInstrJump(J, target >> 2); } @@ -1128,8 +1147,13 @@ void Assembler::jr(Register rs) { void Assembler::jal(int32_t target) { +#ifdef DEBUG + // Get pc of delay slot. + uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); + bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; + ASSERT(in_range && ((target & 3) == 0)); +#endif positions_recorder()->WriteRecordedPositions(); - ASSERT(is_uint28(target) && ((target & 3) == 0)); GenInstrJump(JAL, target >> 2); } @@ -1142,6 +1166,32 @@ void Assembler::jalr(Register rs, Register rd) { } +void Assembler::j_or_jr(int32_t target, Register rs) { + // Get pc of delay slot. + uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); + bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; + + if (in_range) { + j(target); + } else { + jr(t9); + } +} + + +void Assembler::jal_or_jalr(int32_t target, Register rs) { + // Get pc of delay slot. + uint32_t ipc = reinterpret_cast<uint32_t>(pc_ + 1 * kInstrSize); + bool in_range = ((uint32_t)(ipc^target) >> (kImm26Bits+kImmFieldShift)) == 0; + + if (in_range) { + jal(target); + } else { + jalr(t9); + } +} + + //-------Data-processing-instructions--------- // Arithmetic. @@ -1614,6 +1664,13 @@ void Assembler::cfc1(Register rt, FPUControlRegister fs) { GenInstrRegister(COP1, CFC1, rt, fs); } +void Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { + uint64_t i; + memcpy(&i, &d, 8); + + *lo = i & 0xffffffff; + *hi = i >> 32; +} // Arithmetic. @@ -1972,10 +2029,15 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { } if (rinfo.rmode() != RelocInfo::NONE) { // Don't record external references unless the heap will be serialized. - if (rmode == RelocInfo::EXTERNAL_REFERENCE && - !Serializer::enabled() && - !FLAG_debug_code) { - return; + if (rmode == RelocInfo::EXTERNAL_REFERENCE) { +#ifdef DEBUG + if (!Serializer::enabled()) { + Serializer::TooLateToEnableNow(); + } +#endif + if (!Serializer::enabled() && !emit_debug_code()) { + return; + } } ASSERT(buffer_space() >= kMaxRelocSize); // Too late to grow buffer here. if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { @@ -2070,30 +2132,142 @@ Address Assembler::target_address_at(Address pc) { } +// On Mips, a target address is stored in a lui/ori instruction pair, each +// of which load 16 bits of the 32-bit address to a register. +// Patching the address must replace both instr, and flush the i-cache. +// +// There is an optimization below, which emits a nop when the address +// fits in just 16 bits. This is unlikely to help, and should be benchmarked, +// and possibly removed. void Assembler::set_target_address_at(Address pc, Address target) { - // On MIPS we patch the address into lui/ori instruction pair. - - // First check we have an li (lui/ori pair). Instr instr2 = instr_at(pc + kInstrSize); + uint32_t rt_code = GetRtField(instr2); + uint32_t* p = reinterpret_cast<uint32_t*>(pc); + uint32_t itarget = reinterpret_cast<uint32_t>(target); + #ifdef DEBUG + // Check we have the result from a li macro-instruction, using instr pair. Instr instr1 = instr_at(pc); - - // Check we have indeed the result from a li with MustUseReg true. CHECK((GetOpcodeField(instr1) == LUI && GetOpcodeField(instr2) == ORI)); #endif - uint32_t rt_code = GetRtField(instr2); - uint32_t* p = reinterpret_cast<uint32_t*>(pc); - uint32_t itarget = reinterpret_cast<uint32_t>(target); - - // lui rt, high-16. - // ori rt rt, low-16. + // Must use 2 instructions to insure patchable code => just use lui and ori. + // lui rt, upper-16. + // ori rt rt, lower-16. *p = LUI | rt_code | ((itarget & kHiMask) >> kLuiShift); *(p+1) = ORI | rt_code | (rt_code << 5) | (itarget & kImm16Mask); - CPU::FlushICache(pc, 2 * sizeof(int32_t)); + // The following code is an optimization for the common case of Call() + // or Jump() which is load to register, and jump through register: + // li(t9, address); jalr(t9) (or jr(t9)). + // If the destination address is in the same 256 MB page as the call, it + // is faster to do a direct jal, or j, rather than jump thru register, since + // that lets the cpu pipeline prefetch the target address. However each + // time the address above is patched, we have to patch the direct jal/j + // instruction, as well as possibly revert to jalr/jr if we now cross a + // 256 MB page. Note that with the jal/j instructions, we do not need to + // load the register, but that code is left, since it makes it easy to + // revert this process. A further optimization could try replacing the + // li sequence with nops. + // This optimization can only be applied if the rt-code from instr2 is the + // register used for the jalr/jr. Finally, we have to skip 'jr ra', which is + // mips return. Occasionally this lands after an li(). + + Instr instr3 = instr_at(pc + 2 * kInstrSize); + uint32_t ipc = reinterpret_cast<uint32_t>(pc + 3 * kInstrSize); + bool in_range = + ((uint32_t)(ipc ^ itarget) >> (kImm26Bits + kImmFieldShift)) == 0; + uint32_t target_field = (uint32_t)(itarget & kJumpAddrMask) >> kImmFieldShift; + bool patched_jump = false; + +#ifndef ALLOW_JAL_IN_BOUNDARY_REGION + // This is a workaround to the 24k core E156 bug (affect some 34k cores also). + // Since the excluded space is only 64KB out of 256MB (0.02 %), we will just + // apply this workaround for all cores so we don't have to identify the core. + if (in_range) { + // The 24k core E156 bug has some very specific requirements, we only check + // the most simple one: if the address of the delay slot instruction is in + // the first or last 32 KB of the 256 MB segment. + uint32_t segment_mask = ((256 * MB) - 1) ^ ((32 * KB) - 1); + uint32_t ipc_segment_addr = ipc & segment_mask; + if (ipc_segment_addr == 0 || ipc_segment_addr == segment_mask) + in_range = false; + } +#endif + + if (IsJalr(instr3)) { + // Try to convert JALR to JAL. + if (in_range && GetRt(instr2) == GetRs(instr3)) { + *(p+2) = JAL | target_field; + patched_jump = true; + } + } else if (IsJr(instr3)) { + // Try to convert JR to J, skip returns (jr ra). + bool is_ret = static_cast<int>(GetRs(instr3)) == ra.code(); + if (in_range && !is_ret && GetRt(instr2) == GetRs(instr3)) { + *(p+2) = J | target_field; + patched_jump = true; + } + } else if (IsJal(instr3)) { + if (in_range) { + // We are patching an already converted JAL. + *(p+2) = JAL | target_field; + } else { + // Patch JAL, but out of range, revert to JALR. + // JALR rs reg is the rt reg specified in the ORI instruction. + uint32_t rs_field = GetRt(instr2) << kRsShift; + uint32_t rd_field = ra.code() << kRdShift; // Return-address (ra) reg. + *(p+2) = SPECIAL | rs_field | rd_field | JALR; + } + patched_jump = true; + } else if (IsJ(instr3)) { + if (in_range) { + // We are patching an already converted J (jump). + *(p+2) = J | target_field; + } else { + // Trying patch J, but out of range, just go back to JR. + // JR 'rs' reg is the 'rt' reg specified in the ORI instruction (instr2). + uint32_t rs_field = GetRt(instr2) << kRsShift; + *(p+2) = SPECIAL | rs_field | JR; + } + patched_jump = true; + } + + CPU::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t)); } +void Assembler::JumpLabelToJumpRegister(Address pc) { + // Address pc points to lui/ori instructions. + // Jump to label may follow at pc + 2 * kInstrSize. + uint32_t* p = reinterpret_cast<uint32_t*>(pc); +#ifdef DEBUG + Instr instr1 = instr_at(pc); +#endif + Instr instr2 = instr_at(pc + 1 * kInstrSize); + Instr instr3 = instr_at(pc + 2 * kInstrSize); + bool patched = false; + + if (IsJal(instr3)) { + ASSERT(GetOpcodeField(instr1) == LUI); + ASSERT(GetOpcodeField(instr2) == ORI); + + uint32_t rs_field = GetRt(instr2) << kRsShift; + uint32_t rd_field = ra.code() << kRdShift; // Return-address (ra) reg. + *(p+2) = SPECIAL | rs_field | rd_field | JALR; + patched = true; + } else if (IsJ(instr3)) { + ASSERT(GetOpcodeField(instr1) == LUI); + ASSERT(GetOpcodeField(instr2) == ORI); + + uint32_t rs_field = GetRt(instr2) << kRsShift; + *(p+2) = SPECIAL | rs_field | JR; + patched = true; + } + + if (patched) { + CPU::FlushICache(pc+2, sizeof(Address)); + } +} } } // namespace v8::internal diff --git a/deps/v8/src/mips/assembler-mips.h b/deps/v8/src/mips/assembler-mips.h index e5077bee5a..38e9537afb 100644 --- a/deps/v8/src/mips/assembler-mips.h +++ b/deps/v8/src/mips/assembler-mips.h @@ -168,24 +168,36 @@ Register ToRegister(int num); // Coprocessor register. struct FPURegister { static const int kNumRegisters = v8::internal::kNumFPURegisters; - // f0 has been excluded from allocation. This is following ia32 - // where xmm0 is excluded. - static const int kNumAllocatableRegisters = 15; + + // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers + // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to + // number of Double regs (64-bit regs, or FPU-reg-pairs). + + // A few double registers are reserved: one as a scratch register and one to + // hold 0.0. + // f28: 0.0 + // f30: scratch register. + static const int kNumReservedRegisters = 2; + static const int kNumAllocatableRegisters = kNumRegisters / 2 - + kNumReservedRegisters; + static int ToAllocationIndex(FPURegister reg) { - ASSERT(reg.code() != 0); ASSERT(reg.code() % 2 == 0); - return (reg.code() / 2) - 1; + ASSERT(reg.code() / 2 < kNumAllocatableRegisters); + ASSERT(reg.is_valid()); + return (reg.code() / 2); } static FPURegister FromAllocationIndex(int index) { ASSERT(index >= 0 && index < kNumAllocatableRegisters); - return from_code((index + 1) * 2); + return from_code(index * 2); } static const char* AllocationIndexToString(int index) { ASSERT(index >= 0 && index < kNumAllocatableRegisters); const char* const names[] = { + "f0", "f2", "f4", "f6", @@ -198,9 +210,7 @@ struct FPURegister { "f20", "f22", "f24", - "f26", - "f28", - "f30" + "f26" }; return names[index]; } @@ -212,6 +222,23 @@ struct FPURegister { bool is_valid() const { return 0 <= code_ && code_ < kNumFPURegisters ; } bool is(FPURegister creg) const { return code_ == creg.code_; } + FPURegister low() const { + // Find low reg of a Double-reg pair, which is the reg itself. + ASSERT(code_ % 2 == 0); // Specified Double reg must be even. + FPURegister reg; + reg.code_ = code_; + ASSERT(reg.is_valid()); + return reg; + } + FPURegister high() const { + // Find high reg of a Doubel-reg pair, which is reg + 1. + ASSERT(code_ % 2 == 0); // Specified Double reg must be even. + FPURegister reg; + reg.code_ = code_ + 1; + ASSERT(reg.is_valid()); + return reg; + } + int code() const { ASSERT(is_valid()); return code_; @@ -228,9 +255,19 @@ struct FPURegister { int code_; }; +// V8 now supports the O32 ABI, and the FPU Registers are organized as 32 +// 32-bit registers, f0 through f31. When used as 'double' they are used +// in pairs, starting with the even numbered register. So a double operation +// on f0 really uses f0 and f1. +// (Modern mips hardware also supports 32 64-bit registers, via setting +// (priviledged) Status Register FR bit to 1. This is used by the N32 ABI, +// but it is not in common use. Someday we will want to support this in v8.) + +// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. typedef FPURegister DoubleRegister; +typedef FPURegister FloatRegister; -const FPURegister no_creg = { -1 }; +const FPURegister no_freg = { -1 }; const FPURegister f0 = { 0 }; // Return value in hard float mode. const FPURegister f1 = { 1 }; @@ -265,6 +302,8 @@ const FPURegister f29 = { 29 }; const FPURegister f30 = { 30 }; const FPURegister f31 = { 31 }; +const FPURegister kDoubleRegZero = f28; + // FPU (coprocessor 1) control registers. // Currently only FCSR (#31) is implemented. struct FPUControlRegister { @@ -331,6 +370,10 @@ class MemOperand : public Operand { explicit MemOperand(Register rn, int32_t offset = 0); int32_t offset() const { return offset_; } + bool OffsetIsInt16Encodable() const { + return is_int16(offset_); + } + private: int32_t offset_; @@ -504,6 +547,8 @@ class Assembler : public AssemblerBase { static Address target_address_at(Address pc); static void set_target_address_at(Address pc, Address target); + static void JumpLabelToJumpRegister(Address pc); + // This sets the branch destination (which gets loaded at the call address). // This is for calls and branches within generated code. inline static void set_target_at(Address instruction_payload, @@ -534,9 +579,13 @@ class Assembler : public AssemblerBase { static const int kExternalTargetSize = 0 * kInstrSize; // Number of consecutive instructions used to store 32bit constant. - // Used in RelocInfo::target_address_address() function to tell serializer - // address of the instruction that follows LUI/ORI instruction pair. - static const int kInstructionsFor32BitConstant = 2; + // Before jump-optimizations, this constant was used in + // RelocInfo::target_address_address() function to tell serializer address of + // the instruction that follows LUI/ORI instruction pair. Now, with new jump + // optimization, where jump-through-register instruction that usually + // follows LUI/ORI pair is substituted with J/JAL, this constant equals + // to 3 instructions (LUI+ORI+J/JAL/JR/JALR). + static const int kInstructionsFor32BitConstant = 3; // Distance between the instruction referring to the address of the call // target and the return address. @@ -623,6 +672,8 @@ class Assembler : public AssemblerBase { void jal(int32_t target); void jalr(Register rs, Register rd = ra); void jr(Register target); + void j_or_jr(int32_t target, Register rs); + void jal_or_jalr(int32_t target, Register rs); //-------Data-processing-instructions--------- @@ -892,6 +943,10 @@ class Assembler : public AssemblerBase { static bool IsLui(Instr instr); static bool IsOri(Instr instr); + static bool IsJal(Instr instr); + static bool IsJr(Instr instr); + static bool IsJalr(Instr instr); + static bool IsNop(Instr instr, unsigned int type); static bool IsPop(Instr instr); static bool IsPush(Instr instr); @@ -976,6 +1031,8 @@ class Assembler : public AssemblerBase { return internal_trampoline_exception_; } + void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi); + bool is_trampoline_emitted() const { return trampoline_emitted_; } @@ -1159,6 +1216,7 @@ class Assembler : public AssemblerBase { } return trampoline_slot; } + private: int start_; int end_; diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc index 1d528946c3..521b8e58f0 100644 --- a/deps/v8/src/mips/code-stubs-mips.cc +++ b/deps/v8/src/mips/code-stubs-mips.cc @@ -3591,7 +3591,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ li(t0, Operand(ExternalReference::the_hole_value_location(masm->isolate()))); __ lw(a3, MemOperand(t0)); - __ li(t0, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, masm->isolate()))); __ lw(v0, MemOperand(t0)); __ sw(a3, MemOperand(t0)); @@ -3714,7 +3714,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; __ li(t2, Operand(Smi::FromInt(marker))); __ li(t1, Operand(Smi::FromInt(marker))); - __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address, + __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, masm->isolate()))); __ lw(t0, MemOperand(t0)); __ Push(t3, t2, t1, t0); @@ -3739,7 +3739,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // If this is the outermost JS call, set js_entry_sp value. Label non_outermost_js; - ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, + ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, masm->isolate()); __ li(t1, Operand(ExternalReference(js_entry_sp))); __ lw(t2, MemOperand(t1)); @@ -3762,7 +3762,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // exception field in the JSEnv and return a failure sentinel. // Coming in here the fp will be invalid because the PushTryHandler below // sets it to 0 to signal the existence of the JSEntry frame. - __ li(t0, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, masm->isolate()))); __ sw(v0, MemOperand(t0)); // We come back from 'invoke'. result is in v0. __ li(v0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); @@ -3781,7 +3781,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { __ li(t0, Operand(ExternalReference::the_hole_value_location(masm->isolate()))); __ lw(t1, MemOperand(t0)); - __ li(t0, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, masm->isolate()))); __ sw(t1, MemOperand(t0)); @@ -3832,7 +3832,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Restore the top frame descriptors from the stack. __ pop(t1); - __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address, + __ li(t0, Operand(ExternalReference(Isolate::kCEntryFPAddress, masm->isolate()))); __ sw(t1, MemOperand(t0)); @@ -4718,7 +4718,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { __ li(a1, Operand( ExternalReference::the_hole_value_location(masm->isolate()))); __ lw(a1, MemOperand(a1, 0)); - __ li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address, + __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, masm->isolate()))); __ lw(v0, MemOperand(a2, 0)); __ Branch(&runtime, eq, v0, Operand(a1)); diff --git a/deps/v8/src/mips/constants-mips.cc b/deps/v8/src/mips/constants-mips.cc index 96a23338d1..d0a7af5c35 100644 --- a/deps/v8/src/mips/constants-mips.cc +++ b/deps/v8/src/mips/constants-mips.cc @@ -191,6 +191,7 @@ bool Instruction::IsLinkingInstruction() const { const int op = OpcodeFieldRaw(); switch (op) { case JAL: + return true; case REGIMM: switch (RtFieldRaw()) { case BGEZAL: @@ -272,7 +273,7 @@ Instruction::Type Instruction::InstructionType() const { case MOVCI: return kRegisterType; default: - UNREACHABLE(); + return kUnsupported; }; break; case SPECIAL2: @@ -281,7 +282,7 @@ Instruction::Type Instruction::InstructionType() const { case CLZ: return kRegisterType; default: - UNREACHABLE(); + return kUnsupported; }; break; case SPECIAL3: @@ -290,7 +291,7 @@ Instruction::Type Instruction::InstructionType() const { case EXT: return kRegisterType; default: - UNREACHABLE(); + return kUnsupported; }; break; case COP1: // Coprocessor instructions. @@ -341,7 +342,7 @@ Instruction::Type Instruction::InstructionType() const { case JAL: return kJumpType; default: - UNREACHABLE(); + return kUnsupported; }; return kUnsupported; } diff --git a/deps/v8/src/mips/constants-mips.h b/deps/v8/src/mips/constants-mips.h index ede9688a68..d76ae59ff6 100644 --- a/deps/v8/src/mips/constants-mips.h +++ b/deps/v8/src/mips/constants-mips.h @@ -204,6 +204,10 @@ static const int kImm26Bits = 26; static const int kImm28Shift = 0; static const int kImm28Bits = 28; +// In branches and jumps immediate fields point to words, not bytes, +// and are therefore shifted by 2. +static const int kImmFieldShift = 2; + static const int kFsShift = 11; static const int kFsBits = 5; static const int kFtShift = 16; @@ -233,7 +237,7 @@ static const int kFunctionFieldMask = static const int kHiMask = 0xffff << 16; static const int kLoMask = 0xffff; static const int kSignMask = 0x80000000; - +static const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; // ----- MIPS Opcodes and Function Fields. // We use this presentation to stay close to the table representation in @@ -290,12 +294,12 @@ enum Opcode { enum SecondaryField { // SPECIAL Encoding of Function Field. SLL = ((0 << 3) + 0), + MOVCI = ((0 << 3) + 1), SRL = ((0 << 3) + 2), SRA = ((0 << 3) + 3), SLLV = ((0 << 3) + 4), SRLV = ((0 << 3) + 6), SRAV = ((0 << 3) + 7), - MOVCI = ((0 << 3) + 1), JR = ((1 << 3) + 0), JALR = ((1 << 3) + 1), @@ -498,14 +502,38 @@ inline Condition ReverseCondition(Condition cc) { // ----- Coprocessor conditions. enum FPUCondition { - F, // False. - UN, // Unordered. - EQ, // Equal. - UEQ, // Unordered or Equal. - OLT, // Ordered or Less Than. - ULT, // Unordered or Less Than. - OLE, // Ordered or Less Than or Equal. - ULE // Unordered or Less Than or Equal. + kNoFPUCondition = -1, + + F = 0, // False. + UN = 1, // Unordered. + EQ = 2, // Equal. + UEQ = 3, // Unordered or Equal. + OLT = 4, // Ordered or Less Than. + ULT = 5, // Unordered or Less Than. + OLE = 6, // Ordered or Less Than or Equal. + ULE = 7 // Unordered or Less Than or Equal. +}; + + +// FPU rounding modes. +enum FPURoundingMode { + RN = 0 << 0, // Round to Nearest. + RZ = 1 << 0, // Round towards zero. + RP = 2 << 0, // Round towards Plus Infinity. + RM = 3 << 0, // Round towards Minus Infinity. + + // Aliases. + kRoundToNearest = RN, + kRoundToZero = RZ, + kRoundToPlusInf = RP, + kRoundToMinusInf = RM +}; + +static const uint32_t kFPURoundingModeMask = 3 << 0; + +enum CheckForInexactConversion { + kCheckForInexactConversion, + kDontCheckForInexactConversion }; @@ -716,7 +744,7 @@ class Instruction { inline int32_t Imm26Value() const { ASSERT(InstructionType() == kJumpType); - return Bits(kImm16Shift + kImm26Bits - 1, kImm26Shift); + return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); } // Say if the instruction should not be used in a branch delay slot. diff --git a/deps/v8/src/mips/disasm-mips.cc b/deps/v8/src/mips/disasm-mips.cc index 7df5c4175f..fde0c58f08 100644 --- a/deps/v8/src/mips/disasm-mips.cc +++ b/deps/v8/src/mips/disasm-mips.cc @@ -112,7 +112,7 @@ class Decoder { void PrintUImm16(Instruction* instr); void PrintSImm16(Instruction* instr); void PrintXImm16(Instruction* instr); - void PrintImm26(Instruction* instr); + void PrintXImm26(Instruction* instr); void PrintCode(Instruction* instr); // For break and trap instructions. // Printing of instruction name. void PrintInstructionName(Instruction* instr); @@ -273,9 +273,9 @@ void Decoder::PrintXImm16(Instruction* instr) { // Print 26-bit immediate value. -void Decoder::PrintImm26(Instruction* instr) { - int32_t imm = instr->Imm26Value(); - out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); +void Decoder::PrintXImm26(Instruction* instr) { + uint32_t imm = instr->Imm26Value() << kImmFieldShift; + out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); } @@ -383,9 +383,9 @@ int Decoder::FormatOption(Instruction* instr, const char* format) { } return 6; } else { - ASSERT(STRING_STARTS_WITH(format, "imm26")); - PrintImm26(instr); - return 5; + ASSERT(STRING_STARTS_WITH(format, "imm26x")); + PrintXImm26(instr); + return 6; } } case 'r': { // 'r: registers. @@ -926,10 +926,10 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { void Decoder::DecodeTypeJump(Instruction* instr) { switch (instr->OpcodeFieldRaw()) { case J: - Format(instr, "j 'imm26"); + Format(instr, "j 'imm26x"); break; case JAL: - Format(instr, "jal 'imm26"); + Format(instr, "jal 'imm26x"); break; default: UNREACHABLE(); @@ -958,6 +958,7 @@ int Decoder::InstructionDecode(byte* instr_ptr) { break; } default: { + Format(instr, "UNSUPPORTED"); UNSUPPORTED_MIPS(); } } diff --git a/deps/v8/src/mips/frames-mips.h b/deps/v8/src/mips/frames-mips.h index 798ef23b2e..2c838938b7 100644 --- a/deps/v8/src/mips/frames-mips.h +++ b/deps/v8/src/mips/frames-mips.h @@ -87,7 +87,6 @@ static const RegList kCalleeSavedFPU = static const int kNumCalleeSavedFPU = 6; // Number of registers for which space is reserved in safepoints. Must be a // multiple of 8. -// TODO(mips): Only 8 registers may actually be sufficient. Revisit. static const int kNumSafepointRegisters = 24; // Define the list of registers actually saved at safepoints. diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc index d690ca3fcd..b042a3eca3 100644 --- a/deps/v8/src/mips/full-codegen-mips.cc +++ b/deps/v8/src/mips/full-codegen-mips.cc @@ -2042,9 +2042,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr, // Record source position for debugger. SetSourcePosition(expr->position()); // Call the IC initialization code. - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ Call(ic, mode, expr->id()); RecordJSReturnSite(expr); // Restore context register. @@ -2075,9 +2074,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, // Record source position for debugger. SetSourcePosition(expr->position()); // Call the IC initialization code. - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic = - isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); + isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); RecordJSReturnSite(expr); @@ -2098,8 +2096,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, flags); + CallFunctionStub stub(arg_count, flags); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -2197,8 +2194,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { } // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); + CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -3574,9 +3570,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { __ li(a2, Operand(expr->name())); RelocInfo::Mode mode = RelocInfo::CODE_TARGET; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arg_count, - NOT_IN_LOOP, - mode); + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ Call(ic, mode, expr->id()); // Restore context register. __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); diff --git a/deps/v8/src/mips/ic-mips.cc b/deps/v8/src/mips/ic-mips.cc index 5ef35548d6..a76c215a48 100644 --- a/deps/v8/src/mips/ic-mips.cc +++ b/deps/v8/src/mips/ic-mips.cc @@ -146,7 +146,7 @@ static void GenerateDictionaryLoad(MacroAssembler* masm, __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); __ And(at, scratch1, - Operand(PropertyDetails::TypeField::mask() << kSmiTagSize)); + Operand(PropertyDetails::TypeField::kMask << kSmiTagSize)); __ Branch(miss, ne, at, Operand(zero_reg)); // Get the value at the masked, scaled index and return. @@ -196,9 +196,9 @@ static void GenerateDictionaryStore(MacroAssembler* masm, const int kElementsStartOffset = StringDictionary::kHeaderSize + StringDictionary::kElementsStartIndex * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask - = (PropertyDetails::TypeField::mask() | - PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; + const int kTypeAndReadOnlyMask = + (PropertyDetails::TypeField::kMask | + PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); __ And(at, scratch1, Operand(kTypeAndReadOnlyMask)); __ Branch(miss, ne, at, Operand(zero_reg)); @@ -395,7 +395,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, // Probe the stub cache. Code::Flags flags = Code::ComputeFlags(kind, - NOT_IN_LOOP, MONOMORPHIC, extra_ic_state, NORMAL, @@ -732,9 +731,7 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // ----------------------------------- // Probe the stub cache. - Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, - NOT_IN_LOOP, - MONOMORPHIC); + Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC); Isolate::Current()->stub_cache()->GenerateProbe( masm, flags, a0, a2, a3, t0, t1); @@ -1395,10 +1392,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm, // ----------------------------------- // Get the receiver from the stack and probe the stub cache. - Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, - NOT_IN_LOOP, - MONOMORPHIC, - strict_mode); + Code::Flags flags = + Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode); Isolate::Current()->stub_cache()->GenerateProbe( masm, flags, a1, a2, a3, t0, t1); diff --git a/deps/v8/src/mips/macro-assembler-mips.cc b/deps/v8/src/mips/macro-assembler-mips.cc index 1a37d65927..4c48ef183c 100644 --- a/deps/v8/src/mips/macro-assembler-mips.cc +++ b/deps/v8/src/mips/macro-assembler-mips.cc @@ -441,7 +441,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss, const int kDetailsOffset = NumberDictionary::kElementsStartOffset + 2 * kPointerSize; lw(reg1, FieldMemOperand(reg2, kDetailsOffset)); - And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask()))); + And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); Branch(miss, ne, at, Operand(zero_reg)); // Get the value at the masked, scaled index and return. @@ -2337,7 +2337,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, li(t0, Operand(StackHandler::TRY_FINALLY)); } // Save the current handler as the next handler. - li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + li(t2, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); lw(t1, MemOperand(t2)); addiu(sp, sp, -StackHandlerConstants::kSize); @@ -2359,7 +2359,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, li(t0, Operand(StackHandler::ENTRY)); // Save the current handler as the next handler. - li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + li(t2, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); lw(t1, MemOperand(t2)); ASSERT(Smi::FromInt(0) == 0); // Used for no context. @@ -2381,7 +2381,7 @@ void MacroAssembler::PopTryHandler() { STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); pop(a1); Addu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); - li(at, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + li(at, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); sw(a1, MemOperand(at)); } @@ -2399,7 +2399,7 @@ void MacroAssembler::Throw(Register value) { STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); // Drop the sp to the top of the handler. - li(a3, Operand(ExternalReference(Isolate::k_handler_address, + li(a3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); lw(sp, MemOperand(a3)); @@ -2462,7 +2462,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, Move(v0, value); // Drop sp to the top stack handler. - li(a3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); + li(a3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); lw(sp, MemOperand(a3)); // Unwind the handlers until the ENTRY handler is found. @@ -2485,7 +2485,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, if (type == OUT_OF_MEMORY) { // Set external caught exception to false. ExternalReference external_caught( - Isolate::k_external_caught_exception_address, isolate()); + Isolate::kExternalCaughtExceptionAddress, isolate()); li(a0, Operand(false, RelocInfo::NONE)); li(a2, Operand(external_caught)); sw(a0, MemOperand(a2)); @@ -2493,7 +2493,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, // Set pending exception and v0 to out of memory exception. Failure* out_of_memory = Failure::OutOfMemoryException(); li(v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); - li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address, + li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, isolate()))); sw(v0, MemOperand(a2)); } @@ -2975,7 +2975,7 @@ void MacroAssembler::CopyBytes(Register src, void MacroAssembler::CheckFastElements(Register map, Register scratch, Label* fail) { - STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); + STATIC_ASSERT(FAST_ELEMENTS == 0); lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset)); Branch(fail, hi, scratch, Operand(Map::kMaximumBitField2FastElementValue)); } @@ -3973,9 +3973,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, sw(t8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); // Save the frame pointer and the context in top. - li(t8, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); + li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); sw(fp, MemOperand(t8)); - li(t8, Operand(ExternalReference(Isolate::k_context_address, isolate()))); + li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); sw(cp, MemOperand(t8)); const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); @@ -4025,11 +4025,11 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, } // Clear top frame. - li(t8, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); + li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); sw(zero_reg, MemOperand(t8)); // Restore current context from top and clear it in debug mode. - li(t8, Operand(ExternalReference(Isolate::k_context_address, isolate()))); + li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); lw(cp, MemOperand(t8)); #ifdef DEBUG sw(a3, MemOperand(t8)); diff --git a/deps/v8/src/mips/regexp-macro-assembler-mips.h b/deps/v8/src/mips/regexp-macro-assembler-mips.h index 7fe0c8865e..d42d4cf67e 100644 --- a/deps/v8/src/mips/regexp-macro-assembler-mips.h +++ b/deps/v8/src/mips/regexp-macro-assembler-mips.h @@ -118,6 +118,7 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler { static int CheckStackGuardState(Address* return_address, Code* re_code, Address re_frame); + private: // Offsets from frame_pointer() of function parameters and stored registers. static const int kFramePointer = 0; diff --git a/deps/v8/src/mips/simulator-mips.cc b/deps/v8/src/mips/simulator-mips.cc index 7628237037..17c18977c7 100644 --- a/deps/v8/src/mips/simulator-mips.cc +++ b/deps/v8/src/mips/simulator-mips.cc @@ -33,6 +33,7 @@ #if defined(V8_TARGET_ARCH_MIPS) +#include "cpu.h" #include "disasm.h" #include "assembler.h" #include "globals.h" // Need the BitCast. @@ -1215,6 +1216,8 @@ int32_t Simulator::get_pc() const { int Simulator::ReadW(int32_t addr, Instruction* instr) { if (addr >=0 && addr < 0x400) { // This has to be a NULL-dereference, drop into debugger. + PrintF("Memory read from bad address: 0x%08x, pc=0x%08x\n", + addr, reinterpret_cast<intptr_t>(instr)); MipsDebugger dbg(this); dbg.Debug(); } @@ -1234,6 +1237,8 @@ int Simulator::ReadW(int32_t addr, Instruction* instr) { void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { if (addr >= 0 && addr < 0x400) { // This has to be a NULL-dereference, drop into debugger. + PrintF("Memory write to bad address: 0x%08x, pc=0x%08x\n", + addr, reinterpret_cast<intptr_t>(instr)); MipsDebugger dbg(this); dbg.Debug(); } diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc index d0f06e4710..5b949734fb 100644 --- a/deps/v8/src/mips/stub-cache-mips.cc +++ b/deps/v8/src/mips/stub-cache-mips.cc @@ -3099,7 +3099,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { // -- a1 : receiver // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(a1, @@ -3191,7 +3191,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { // -- a3 : scratch // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; MaybeObject* maybe_stub = KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); @@ -3442,25 +3442,25 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( } -static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) { +static bool IsElementTypeSigned(ElementsKind elements_kind) { switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: return true; - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: return false; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); return false; } @@ -3470,7 +3470,7 @@ static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) { void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ---------- S t a t e -------------- // -- ra : return address // -- a0 : key @@ -3505,32 +3505,32 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( Register value = a2; switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ srl(t2, key, 1); __ addu(t3, a3, t2); __ lb(value, MemOperand(t3, 0)); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ srl(t2, key, 1); __ addu(t3, a3, t2); __ lbu(value, MemOperand(t3, 0)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: __ addu(t3, a3, key); __ lh(value, MemOperand(t3, 0)); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ addu(t3, a3, key); __ lhu(value, MemOperand(t3, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ sll(t2, key, 1); __ addu(t3, a3, t2); __ lw(value, MemOperand(t3, 0)); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: __ sll(t3, t2, 2); __ addu(t3, a3, t3); if (CpuFeatures::IsSupported(FPU)) { @@ -3540,7 +3540,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ lw(value, MemOperand(t3, 0)); } break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: __ sll(t2, key, 2); __ addu(t3, a3, t2); if (CpuFeatures::IsSupported(FPU)) { @@ -3552,10 +3552,10 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ lw(a3, MemOperand(t3, Register::kSizeInBytes)); } break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3569,7 +3569,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // f0: value (if FPU is supported) // a2/a3: value (if FPU is not supported) - if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { + if (elements_kind == EXTERNAL_INT_ELEMENTS) { // For the Int and UnsignedInt array types, we need to see whether // the value can be represented in a Smi. If not, we need to convert // it to a HeapNumber. @@ -3611,7 +3611,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ sw(dst2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); __ Ret(); } - } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { + } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { // The test is different for unsigned int values. Since we need // the value to be in the range of a positive smi, we can't // handle either of the top two bits being set in the value. @@ -3682,7 +3682,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ mov(v0, t2); __ Ret(); } - } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. if (CpuFeatures::IsSupported(FPU)) { @@ -3749,7 +3749,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ Ret(); } - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { if (CpuFeatures::IsSupported(FPU)) { CpuFeatures::Scope scope(FPU); // Allocate a HeapNumber for the result. Don't use a0 and a1 as @@ -3803,7 +3803,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ---------- S t a t e -------------- // -- a0 : value // -- a1 : key @@ -3838,7 +3838,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // a3: external array. // t0: key (integer). - if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { // Double to pixel conversion is only implemented in the runtime for now. __ JumpIfNotSmi(value, &slow); } else { @@ -3852,7 +3852,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // t1: value (integer). switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: { + case EXTERNAL_PIXEL_ELEMENTS: { // Clamp the value to [0..255]. // v0 is used as a scratch register here. Label done; @@ -3869,28 +3869,28 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ sb(t1, MemOperand(t8, 0)); } break; - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ addu(t8, a3, t0); __ sb(t1, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ sll(t8, t0, 1); __ addu(t8, a3, t8); __ sh(t1, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ sll(t8, t0, 2); __ addu(t8, a3, t8); __ sw(t1, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: // Perform int-to-float conversion and store to memory. StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4); break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: __ sll(t8, t0, 3); __ addu(a3, a3, t8); // a3: effective address of the double element @@ -3912,10 +3912,10 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ sw(t3, MemOperand(a3, Register::kSizeInBytes)); } break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3924,7 +3924,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ mov(v0, value); __ Ret(); - if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { // a3: external array. // t0: index (integer). __ bind(&check_heap_number); @@ -3945,12 +3945,12 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ cvt_s_d(f0, f0); __ sll(t8, t0, 2); __ addu(t8, a3, t8); __ swc1(f0, MemOperand(t8, 0)); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ sll(t8, t0, 3); __ addu(t8, a3, t8); __ sdc1(f0, MemOperand(t8, 0)); @@ -3958,30 +3958,30 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ addu(t8, a3, t0); __ sb(t3, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ sll(t8, t0, 1); __ addu(t8, a3, t8); __ sh(t3, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ sll(t8, t0, 2); __ addu(t8, a3, t8); __ sw(t3, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3997,7 +3997,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset)); __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset)); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { Label done, nan_or_infinity_or_zero; static const int kMantissaInHiWordShift = kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; @@ -4062,7 +4062,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ srl(t4, t4, kMantissaInLoWordShift); __ or_(t3, t6, t4); __ Branch(&done); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ sll(t8, t0, 3); __ addu(t8, a3, t8); // t8: effective address of destination element. @@ -4128,30 +4128,30 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // Result is in t3. // This switch block should be exactly the same as above (FPU mode). switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ addu(t8, a3, t0); __ sb(t3, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ sll(t8, t0, 1); __ addu(t8, a3, t8); __ sh(t3, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ sll(t8, t0, 2); __ addu(t8, a3, t8); __ sw(t3, MemOperand(t8, 0)); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } diff --git a/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc index a3dc19357f..8de7162ab2 100644 --- a/deps/v8/src/objects-debug.cc +++ b/deps/v8/src/objects-debug.cc @@ -164,6 +164,9 @@ void HeapObject::HeapObjectVerify() { case JS_PROXY_TYPE: JSProxy::cast(this)->JSProxyVerify(); break; + case JS_FUNCTION_PROXY_TYPE: + JSFunctionProxy::cast(this)->JSFunctionProxyVerify(); + break; case FOREIGN_TYPE: Foreign::cast(this)->ForeignVerify(); break; @@ -536,6 +539,15 @@ void JSProxy::JSProxyVerify() { VerifyPointer(handler()); } + +void JSFunctionProxy::JSFunctionProxyVerify() { + ASSERT(IsJSFunctionProxy()); + JSProxyVerify(); + VerifyPointer(call_trap()); + VerifyPointer(construct_trap()); +} + + void Foreign::ForeignVerify() { ASSERT(IsForeign()); } diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 588b0f63a8..bb24a2f854 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -2000,7 +2000,7 @@ bool DescriptorArray::IsProperty(int descriptor_number) { bool DescriptorArray::IsTransition(int descriptor_number) { PropertyType t = GetType(descriptor_number); return t == MAP_TRANSITION || t == CONSTANT_TRANSITION || - t == EXTERNAL_ARRAY_TRANSITION; + t == ELEMENTS_TRANSITION; } @@ -2867,7 +2867,7 @@ Code::Flags Code::flags() { void Code::set_flags(Code::Flags flags) { - STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1); + STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); // Make sure that all call stubs have an arguments count. ASSERT((ExtractKindFromFlags(flags) != CALL_IC && ExtractKindFromFlags(flags) != KEYED_CALL_IC) || @@ -2881,11 +2881,6 @@ Code::Kind Code::kind() { } -InLoopFlag Code::ic_in_loop() { - return ExtractICInLoopFromFlags(flags()); -} - - InlineCacheState Code::ic_state() { InlineCacheState result = ExtractICStateFromFlags(flags()); // Only allow uninitialized or debugger states for non-IC code @@ -2951,13 +2946,31 @@ void Code::set_optimizable(bool value) { bool Code::has_deoptimization_support() { ASSERT(kind() == FUNCTION); - return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1; + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + return FullCodeFlagsHasDeoptimizationSupportField::decode(flags); } void Code::set_has_deoptimization_support(bool value) { ASSERT(kind() == FUNCTION); - WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0); + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value); + WRITE_BYTE_FIELD(this, kFullCodeFlags, flags); +} + + +bool Code::has_debug_break_slots() { + ASSERT(kind() == FUNCTION); + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + return FullCodeFlagsHasDebugBreakSlotsField::decode(flags); +} + + +void Code::set_has_debug_break_slots(bool value) { + ASSERT(kind() == FUNCTION); + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value); + WRITE_BYTE_FIELD(this, kFullCodeFlags, flags); } @@ -3091,7 +3104,6 @@ bool Code::is_inline_cache_stub() { Code::Flags Code::ComputeFlags(Kind kind, - InLoopFlag in_loop, InlineCacheState ic_state, ExtraICState extra_ic_state, PropertyType type, @@ -3100,26 +3112,17 @@ Code::Flags Code::ComputeFlags(Kind kind, // Extra IC state is only allowed for call IC stubs or for store IC // stubs. ASSERT(extra_ic_state == kNoExtraICState || - (kind == CALL_IC) || - (kind == STORE_IC) || - (kind == KEYED_STORE_IC)); + kind == CALL_IC || + kind == STORE_IC || + kind == KEYED_STORE_IC); // Compute the bit mask. - int bits = kind << kFlagsKindShift; - if (in_loop) bits |= kFlagsICInLoopMask; - bits |= ic_state << kFlagsICStateShift; - bits |= type << kFlagsTypeShift; - bits |= extra_ic_state << kFlagsExtraICStateShift; - bits |= argc << kFlagsArgumentsCountShift; - if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask; - // Cast to flags and validate result before returning it. - Flags result = static_cast<Flags>(bits); - ASSERT(ExtractKindFromFlags(result) == kind); - ASSERT(ExtractICStateFromFlags(result) == ic_state); - ASSERT(ExtractICInLoopFromFlags(result) == in_loop); - ASSERT(ExtractTypeFromFlags(result) == type); - ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state); - ASSERT(ExtractArgumentsCountFromFlags(result) == argc); - return result; + int bits = KindField::encode(kind) + | ICStateField::encode(ic_state) + | TypeField::encode(type) + | ExtraICStateField::encode(extra_ic_state) + | (argc << kArgumentsCountShift) + | CacheHolderField::encode(holder); + return static_cast<Flags>(bits); } @@ -3127,56 +3130,43 @@ Code::Flags Code::ComputeMonomorphicFlags(Kind kind, PropertyType type, ExtraICState extra_ic_state, InlineCacheHolderFlag holder, - InLoopFlag in_loop, int argc) { - return ComputeFlags( - kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder); + return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder); } Code::Kind Code::ExtractKindFromFlags(Flags flags) { - int bits = (flags & kFlagsKindMask) >> kFlagsKindShift; - return static_cast<Kind>(bits); + return KindField::decode(flags); } InlineCacheState Code::ExtractICStateFromFlags(Flags flags) { - int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift; - return static_cast<InlineCacheState>(bits); + return ICStateField::decode(flags); } Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) { - int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift; - return static_cast<ExtraICState>(bits); -} - - -InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) { - int bits = (flags & kFlagsICInLoopMask); - return bits != 0 ? IN_LOOP : NOT_IN_LOOP; + return ExtraICStateField::decode(flags); } PropertyType Code::ExtractTypeFromFlags(Flags flags) { - int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift; - return static_cast<PropertyType>(bits); + return TypeField::decode(flags); } int Code::ExtractArgumentsCountFromFlags(Flags flags) { - return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift; + return (flags & kArgumentsCountMask) >> kArgumentsCountShift; } InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) { - int bits = (flags & kFlagsCacheInPrototypeMapMask); - return bits != 0 ? PROTOTYPE_MAP : OWN_MAP; + return CacheHolderField::decode(flags); } Code::Flags Code::RemoveTypeFromFlags(Flags flags) { - int bits = flags & ~kFlagsTypeMask; + int bits = flags & ~TypeField::kMask; return static_cast<Flags>(bits); } @@ -3259,7 +3249,7 @@ MaybeObject* Map::GetFastElementsMap() { if (!maybe_obj->ToObject(&obj)) return maybe_obj; } Map* new_map = Map::cast(obj); - new_map->set_elements_kind(JSObject::FAST_ELEMENTS); + new_map->set_elements_kind(FAST_ELEMENTS); isolate()->counters()->map_to_fast_elements()->Increment(); return new_map; } @@ -3272,7 +3262,7 @@ MaybeObject* Map::GetFastDoubleElementsMap() { if (!maybe_obj->ToObject(&obj)) return maybe_obj; } Map* new_map = Map::cast(obj); - new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS); + new_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); isolate()->counters()->map_to_fast_double_elements()->Increment(); return new_map; } @@ -3285,7 +3275,7 @@ MaybeObject* Map::GetSlowElementsMap() { if (!maybe_obj->ToObject(&obj)) return maybe_obj; } Map* new_map = Map::cast(obj); - new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS); + new_map->set_elements_kind(DICTIONARY_ELEMENTS); isolate()->counters()->map_to_slow_elements()->Increment(); return new_map; } @@ -3916,7 +3906,16 @@ void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id, ACCESSORS(JSProxy, handler, Object, kHandlerOffset) -ACCESSORS(JSProxy, padding, Object, kPaddingOffset) +ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset) +ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset) + + +void JSProxy::InitializeBody(int object_size, Object* value) { + ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value)); + for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) { + WRITE_FIELD(this, offset, value); + } +} ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset) @@ -4098,7 +4097,7 @@ void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) { } -JSObject::ElementsKind JSObject::GetElementsKind() { +ElementsKind JSObject::GetElementsKind() { ElementsKind kind = map()->elements_kind(); ASSERT((kind == FAST_ELEMENTS && (elements()->map() == GetHeap()->fixed_array_map() || @@ -4437,9 +4436,7 @@ PropertyAttributes AccessorInfo::property_attributes() { void AccessorInfo::set_property_attributes(PropertyAttributes attributes) { - ASSERT(AttributesField::is_valid(attributes)); - int rest_value = flag()->value() & ~AttributesField::mask(); - set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes))); + set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes))); } diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc index 35735724e8..0398572f90 100644 --- a/deps/v8/src/objects-printer.cc +++ b/deps/v8/src/objects-printer.cc @@ -151,6 +151,9 @@ void HeapObject::HeapObjectPrint(FILE* out) { case JS_PROXY_TYPE: JSProxy::cast(this)->JSProxyPrint(out); break; + case JS_FUNCTION_PROXY_TYPE: + JSFunctionProxy::cast(this)->JSFunctionProxyPrint(out); + break; case JS_WEAK_MAP_TYPE: JSWeakMap::cast(this)->JSWeakMapPrint(out); break; @@ -588,6 +591,19 @@ void JSProxy::JSProxyPrint(FILE* out) { } +void JSFunctionProxy::JSFunctionProxyPrint(FILE* out) { + HeapObject::PrintHeader(out, "JSFunctionProxy"); + PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); + PrintF(out, " - handler = "); + handler()->Print(out); + PrintF(out, " - call_trap = "); + call_trap()->Print(out); + PrintF(out, " - construct_trap = "); + construct_trap()->Print(out); + PrintF(out, "\n"); +} + + void JSWeakMap::JSWeakMapPrint(FILE* out) { HeapObject::PrintHeader(out, "JSWeakMap"); PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); diff --git a/deps/v8/src/objects-visiting.cc b/deps/v8/src/objects-visiting.cc index bde9e83153..0aa21dd6ed 100644 --- a/deps/v8/src/objects-visiting.cc +++ b/deps/v8/src/objects-visiting.cc @@ -105,6 +105,11 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId( kVisitStructGeneric, JSProxy::kSize); + case JS_FUNCTION_PROXY_TYPE: + return GetVisitorIdForSize(kVisitStruct, + kVisitStructGeneric, + JSFunctionProxy::kSize); + case FOREIGN_TYPE: return GetVisitorIdForSize(kVisitDataObject, kVisitDataObjectGeneric, diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index 00ea4f23db..41b4fd4dbc 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -84,7 +84,7 @@ MaybeObject* Object::ToObject(Context* global_context) { MaybeObject* Object::ToObject() { - if (IsJSObject()) { + if (IsJSReceiver()) { return this; } else if (IsNumber()) { Isolate* isolate = Isolate::Current(); @@ -237,6 +237,7 @@ MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw, // Extract trap function. Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("get"); Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); + if (isolate->has_pending_exception()) return Failure::Exception(); if (trap->IsUndefined()) { // Get the derived `get' property. trap = isolate->derived_get_trap(); @@ -591,7 +592,7 @@ MaybeObject* Object::GetProperty(Object* receiver, return holder->GetPropertyWithInterceptor(recvr, name, attributes); } case MAP_TRANSITION: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: break; @@ -627,6 +628,7 @@ MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { } else if (heap_object->IsBoolean()) { holder = global_context->boolean_function()->instance_prototype(); } else if (heap_object->IsJSProxy()) { + // TODO(rossberg): do something return heap->undefined_value(); // For now... } else { // Undefined and null have no indexed properties. @@ -1173,6 +1175,12 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { HeapNumber::cast(this)->HeapNumberPrint(accumulator); accumulator->Put('>'); break; + case JS_PROXY_TYPE: + accumulator->Add("<JSProxy>"); + break; + case JS_FUNCTION_PROXY_TYPE: + accumulator->Add("<JSFunctionProxy>"); + break; case FOREIGN_TYPE: accumulator->Add("<Foreign>"); break; @@ -1251,6 +1259,9 @@ void HeapObject::IterateBody(InstanceType type, int object_size, case JS_PROXY_TYPE: JSProxy::BodyDescriptor::IterateBody(this, v); break; + case JS_FUNCTION_PROXY_TYPE: + JSFunctionProxy::BodyDescriptor::IterateBody(this, v); + break; case FOREIGN_TYPE: reinterpret_cast<Foreign*>(this)->ForeignIterateBody(v); break; @@ -1435,13 +1446,12 @@ MaybeObject* JSObject::AddFastProperty(String* name, // it's unrelated to properties. int descriptor_index = old_descriptors->Search(name); - // External array transitions are stored in the descriptor for property "", - // which is not a identifier and should have forced a switch to slow - // properties above. + // Element transitions are stored in the descriptor for property "", which is + // not a identifier and should have forced a switch to slow properties above. ASSERT(descriptor_index == DescriptorArray::kNotFound || - old_descriptors->GetType(descriptor_index) != EXTERNAL_ARRAY_TRANSITION); + old_descriptors->GetType(descriptor_index) != ELEMENTS_TRANSITION); bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound || - old_descriptors->GetType(descriptor_index) == EXTERNAL_ARRAY_TRANSITION; + old_descriptors->GetType(descriptor_index) == ELEMENTS_TRANSITION; bool allow_map_transition = can_insert_transition && (isolate->context()->global_context()->object_function()->map() != map()); @@ -1989,61 +1999,25 @@ void Map::LookupInDescriptors(JSObject* holder, } -static JSObject::ElementsKind GetElementsKindFromExternalArrayType( - ExternalArrayType array_type) { - switch (array_type) { - case kExternalByteArray: - return JSObject::EXTERNAL_BYTE_ELEMENTS; - break; - case kExternalUnsignedByteArray: - return JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS; - break; - case kExternalShortArray: - return JSObject::EXTERNAL_SHORT_ELEMENTS; - break; - case kExternalUnsignedShortArray: - return JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS; - break; - case kExternalIntArray: - return JSObject::EXTERNAL_INT_ELEMENTS; - break; - case kExternalUnsignedIntArray: - return JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS; - break; - case kExternalFloatArray: - return JSObject::EXTERNAL_FLOAT_ELEMENTS; - break; - case kExternalDoubleArray: - return JSObject::EXTERNAL_DOUBLE_ELEMENTS; - break; - case kExternalPixelArray: - return JSObject::EXTERNAL_PIXEL_ELEMENTS; - break; - } - UNREACHABLE(); - return JSObject::DICTIONARY_ELEMENTS; -} - - -MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, - bool safe_to_add_transition) { +MaybeObject* Map::GetElementsTransitionMap(ElementsKind elements_kind, + bool safe_to_add_transition) { Heap* current_heap = heap(); DescriptorArray* descriptors = instance_descriptors(); - String* external_array_sentinel_name = current_heap->empty_symbol(); + String* elements_transition_sentinel_name = current_heap->empty_symbol(); if (safe_to_add_transition) { // It's only safe to manipulate the descriptor array if it would be // safe to add a transition. ASSERT(!is_shared()); // no transitions can be added to shared maps. - // Check if the external array transition already exists. + // Check if the elements transition already exists. DescriptorLookupCache* cache = current_heap->isolate()->descriptor_lookup_cache(); - int index = cache->Lookup(descriptors, external_array_sentinel_name); + int index = cache->Lookup(descriptors, elements_transition_sentinel_name); if (index == DescriptorLookupCache::kAbsent) { - index = descriptors->Search(external_array_sentinel_name); + index = descriptors->Search(elements_transition_sentinel_name); cache->Update(descriptors, - external_array_sentinel_name, + elements_transition_sentinel_name, index); } @@ -2051,8 +2025,8 @@ MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, // return it. if (index != DescriptorArray::kNotFound) { PropertyDetails details(PropertyDetails(descriptors->GetDetails(index))); - if (details.type() == EXTERNAL_ARRAY_TRANSITION && - details.array_type() == array_type) { + if (details.type() == ELEMENTS_TRANSITION && + details.elements_kind() == elements_kind) { return descriptors->GetValue(index); } else { safe_to_add_transition = false; @@ -2060,28 +2034,29 @@ MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type, } } - // No transition to an existing external array map. Make a new one. + // No transition to an existing map for the given ElementsKind. Make a new + // one. Object* obj; { MaybeObject* maybe_map = CopyDropTransitions(); if (!maybe_map->ToObject(&obj)) return maybe_map; } Map* new_map = Map::cast(obj); - new_map->set_elements_kind(GetElementsKindFromExternalArrayType(array_type)); + new_map->set_elements_kind(elements_kind); GetIsolate()->counters()->map_to_external_array_elements()->Increment(); // Only remember the map transition if the object's map is NOT equal to the // global object_function's map and there is not an already existing - // non-matching external array transition. + // non-matching element transition. bool allow_map_transition = safe_to_add_transition && (GetIsolate()->context()->global_context()->object_function()->map() != map()); if (allow_map_transition) { // Allocate new instance descriptors for the old map with map transition. - ExternalArrayTransitionDescriptor desc(external_array_sentinel_name, - Map::cast(new_map), - array_type); + ElementsTransitionDescriptor desc(elements_transition_sentinel_name, + Map::cast(new_map), + elements_kind); Object* new_descriptors; MaybeObject* maybe_new_descriptors = descriptors->CopyInsert( &desc, @@ -2248,6 +2223,7 @@ bool JSProxy::HasPropertyWithHandler(String* name_raw) { // Extract trap function. Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("has"); Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); + if (isolate->has_pending_exception()) return Failure::Exception(); if (trap->IsUndefined()) { trap = isolate->derived_has_trap(); } @@ -2278,6 +2254,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( // Extract trap function. Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set"); Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); + if (isolate->has_pending_exception()) return Failure::Exception(); if (trap->IsUndefined()) { trap = isolate->derived_set_trap(); } @@ -2305,6 +2282,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( // Extract trap function. Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("delete"); Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); + if (isolate->has_pending_exception()) return Failure::Exception(); if (trap->IsUndefined()) { Handle<Object> args[] = { handler, trap_name }; Handle<Object> error = isolate->factory()->NewTypeError( @@ -2347,6 +2325,7 @@ MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor"); Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); + if (isolate->has_pending_exception()) return NONE; if (trap->IsUndefined()) { Handle<Object> args[] = { handler, trap_name }; Handle<Object> error = isolate->factory()->NewTypeError( @@ -2373,9 +2352,13 @@ void JSProxy::Fix() { HandleScope scope(isolate); Handle<JSProxy> self(this); - isolate->factory()->BecomeJSObject(self); + if (IsJSFunctionProxy()) { + isolate->factory()->BecomeJSFunction(self); + // Code will be set on the JavaScript side. + } else { + isolate->factory()->BecomeJSObject(self); + } ASSERT(self->IsJSObject()); - // TODO(rossberg): recognize function proxies. } @@ -2498,7 +2481,7 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); } case NULL_DESCRIPTOR: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); default: UNREACHABLE(); @@ -2586,7 +2569,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( // if the value is a function. return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); case NULL_DESCRIPTOR: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); default: UNREACHABLE(); @@ -2867,7 +2850,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: case INTERCEPTOR: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: break; default: UNREACHABLE(); @@ -3414,6 +3397,17 @@ MaybeObject* JSObject::PreventExtensions() { return JSObject::cast(proto)->PreventExtensions(); } + // It's not possible to seal objects with external array elements + if (HasExternalArrayElements()) { + HandleScope scope(isolate); + Handle<Object> object(this); + Handle<Object> error = + isolate->factory()->NewTypeError( + "cant_prevent_ext_external_array_elements", + HandleVector(&object, 1)); + return isolate->Throw(*error); + } + // If there are fast elements we normalize. NumberDictionary* dictionary = NULL; { MaybeObject* maybe = NormalizeElements(); @@ -5082,13 +5076,13 @@ String::FlatContent String::GetFlatContent() { } -SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, - RobustnessFlag robust_flag, - int offset, - int length, - int* length_return) { +SmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls, + RobustnessFlag robust_flag, + int offset, + int length, + int* length_return) { if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { - return SmartPointer<char>(NULL); + return SmartArrayPointer<char>(NULL); } Heap* heap = GetHeap(); @@ -5132,13 +5126,13 @@ SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, character_position++; } result[utf8_byte_position] = 0; - return SmartPointer<char>(result); + return SmartArrayPointer<char>(result); } -SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, - RobustnessFlag robust_flag, - int* length_return) { +SmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls, + RobustnessFlag robust_flag, + int* length_return) { return ToCString(allow_nulls, robust_flag, 0, -1, length_return); } @@ -5169,9 +5163,9 @@ const uc16* String::GetTwoByteData(unsigned start) { } -SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { +SmartArrayPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { - return SmartPointer<uc16>(); + return SmartArrayPointer<uc16>(); } Heap* heap = GetHeap(); @@ -5187,7 +5181,7 @@ SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { result[i++] = character; } result[i] = 0; - return SmartPointer<uc16>(result); + return SmartArrayPointer<uc16>(result); } @@ -6201,7 +6195,7 @@ void Map::CreateBackPointers() { DescriptorArray* descriptors = instance_descriptors(); for (int i = 0; i < descriptors->number_of_descriptors(); i++) { if (descriptors->GetType(i) == MAP_TRANSITION || - descriptors->GetType(i) == EXTERNAL_ARRAY_TRANSITION || + descriptors->GetType(i) == ELEMENTS_TRANSITION || descriptors->GetType(i) == CONSTANT_TRANSITION) { // Get target. Map* target = Map::cast(descriptors->GetValue(i)); @@ -6244,7 +6238,7 @@ void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) { // non-live object. PropertyDetails details(Smi::cast(contents->get(i + 1))); if (details.type() == MAP_TRANSITION || - details.type() == EXTERNAL_ARRAY_TRANSITION || + details.type() == ELEMENTS_TRANSITION || details.type() == CONSTANT_TRANSITION) { Map* target = reinterpret_cast<Map*>(contents->get(i)); ASSERT(target->IsHeapObject()); @@ -6404,7 +6398,7 @@ Object* JSFunction::SetInstanceClassName(String* name) { void JSFunction::PrintName(FILE* out) { - SmartPointer<char> name = shared()->DebugName()->ToCString(); + SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); PrintF(out, "%s", *name); } @@ -7133,7 +7127,7 @@ const char* Code::PropertyType2String(PropertyType type) { case HANDLER: return "HANDLER"; case INTERCEPTOR: return "INTERCEPTOR"; case MAP_TRANSITION: return "MAP_TRANSITION"; - case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION"; + case ELEMENTS_TRANSITION: return "ELEMENTS_TRANSITION"; case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; } @@ -7172,7 +7166,6 @@ void Code::Disassemble(const char* name, FILE* out) { if (is_inline_cache_stub()) { PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); PrintExtraICState(out, kind(), extra_ic_state()); - PrintF(out, "ic_in_loop = %d\n", ic_in_loop() == IN_LOOP); if (ic_state() == MONOMORPHIC) { PrintF(out, "type = %s\n", PropertyType2String(type())); } @@ -7523,7 +7516,7 @@ MaybeObject* JSObject::SetElementsLength(Object* len) { if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { const int value = Smi::cast(smi_length)->value(); if (value < 0) return ArrayLengthRangeError(GetHeap()); - JSObject::ElementsKind elements_kind = GetElementsKind(); + ElementsKind elements_kind = GetElementsKind(); switch (elements_kind) { case FAST_ELEMENTS: case FAST_DOUBLE_ELEMENTS: { diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 53ba981c85..d9c7a82276 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -31,7 +31,7 @@ #include "allocation.h" #include "builtins.h" #include "list.h" -#include "smart-pointer.h" +#include "smart-array-pointer.h" #include "unicode-inl.h" #if V8_TARGET_ARCH_ARM #include "arm/constants-arm.h" @@ -135,6 +135,37 @@ enum PropertyAttributes { namespace v8 { namespace internal { +enum ElementsKind { + // The "fast" kind for tagged values. Must be first to make it possible + // to efficiently check maps if they have fast elements. + FAST_ELEMENTS, + + // The "fast" kind for unwrapped, non-tagged double values. + FAST_DOUBLE_ELEMENTS, + + // The "slow" kind. + DICTIONARY_ELEMENTS, + NON_STRICT_ARGUMENTS_ELEMENTS, + // The "fast" kind for external arrays + EXTERNAL_BYTE_ELEMENTS, + EXTERNAL_UNSIGNED_BYTE_ELEMENTS, + EXTERNAL_SHORT_ELEMENTS, + EXTERNAL_UNSIGNED_SHORT_ELEMENTS, + EXTERNAL_INT_ELEMENTS, + EXTERNAL_UNSIGNED_INT_ELEMENTS, + EXTERNAL_FLOAT_ELEMENTS, + EXTERNAL_DOUBLE_ELEMENTS, + EXTERNAL_PIXEL_ELEMENTS, + + // Derived constants from ElementsKind + FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_BYTE_ELEMENTS, + LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS, + FIRST_ELEMENTS_KIND = FAST_ELEMENTS, + LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS +}; + +static const int kElementsKindCount = + LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1; // PropertyDetails captures type and attributes for a property. // They are used both in property dictionaries and instance descriptors. @@ -143,7 +174,7 @@ class PropertyDetails BASE_EMBEDDED { PropertyDetails(PropertyAttributes attributes, PropertyType type, int index = 0) { - ASSERT(type != EXTERNAL_ARRAY_TRANSITION); + ASSERT(type != ELEMENTS_TRANSITION); ASSERT(TypeField::is_valid(type)); ASSERT(AttributesField::is_valid(attributes)); ASSERT(StorageField::is_valid(index)); @@ -159,19 +190,19 @@ class PropertyDetails BASE_EMBEDDED { PropertyDetails(PropertyAttributes attributes, PropertyType type, - ExternalArrayType array_type) { - ASSERT(type == EXTERNAL_ARRAY_TRANSITION); + ElementsKind elements_kind) { + ASSERT(type == ELEMENTS_TRANSITION); ASSERT(TypeField::is_valid(type)); ASSERT(AttributesField::is_valid(attributes)); - ASSERT(StorageField::is_valid(static_cast<int>(array_type))); + ASSERT(StorageField::is_valid(static_cast<int>(elements_kind))); value_ = TypeField::encode(type) | AttributesField::encode(attributes) - | StorageField::encode(static_cast<int>(array_type)); + | StorageField::encode(static_cast<int>(elements_kind)); ASSERT(type == this->type()); ASSERT(attributes == this->attributes()); - ASSERT(array_type == this->array_type()); + ASSERT(elements_kind == this->elements_kind()); } // Conversion for storing details as Object*. @@ -184,7 +215,7 @@ class PropertyDetails BASE_EMBEDDED { PropertyType t = type(); ASSERT(t != INTERCEPTOR); return t == MAP_TRANSITION || t == CONSTANT_TRANSITION || - t == EXTERNAL_ARRAY_TRANSITION; + t == ELEMENTS_TRANSITION; } bool IsProperty() { @@ -195,9 +226,9 @@ class PropertyDetails BASE_EMBEDDED { int index() { return StorageField::decode(value_); } - ExternalArrayType array_type() { - ASSERT(type() == EXTERNAL_ARRAY_TRANSITION); - return static_cast<ExternalArrayType>(StorageField::decode(value_)); + ElementsKind elements_kind() { + ASSERT(type() == ELEMENTS_TRANSITION); + return static_cast<ElementsKind>(StorageField::decode(value_)); } inline PropertyDetails AsDeleted(); @@ -1463,38 +1494,6 @@ class JSReceiver: public HeapObject { // caching. class JSObject: public JSReceiver { public: - enum ElementsKind { - // The "fast" kind for tagged values. Must be first to make it possible - // to efficiently check maps if they have fast elements. - FAST_ELEMENTS, - - // The "fast" kind for unwrapped, non-tagged double values. - FAST_DOUBLE_ELEMENTS, - - // The "slow" kind. - DICTIONARY_ELEMENTS, - NON_STRICT_ARGUMENTS_ELEMENTS, - // The "fast" kind for external arrays - EXTERNAL_BYTE_ELEMENTS, - EXTERNAL_UNSIGNED_BYTE_ELEMENTS, - EXTERNAL_SHORT_ELEMENTS, - EXTERNAL_UNSIGNED_SHORT_ELEMENTS, - EXTERNAL_INT_ELEMENTS, - EXTERNAL_UNSIGNED_INT_ELEMENTS, - EXTERNAL_FLOAT_ELEMENTS, - EXTERNAL_DOUBLE_ELEMENTS, - EXTERNAL_PIXEL_ELEMENTS, - - // Derived constants from ElementsKind - FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_BYTE_ELEMENTS, - LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS, - FIRST_ELEMENTS_KIND = FAST_ELEMENTS, - LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS - }; - - static const int kElementsKindCount = - LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1; - // [properties]: Backing storage for properties. // properties is a FixedArray in the fast case and a Dictionary in the // slow case. @@ -3154,7 +3153,6 @@ class ByteArray: public FixedArrayBase { // raised rather than being silently ignored. class ExternalArray: public FixedArrayBase { public: - inline bool is_the_hole(int index) { return false; } // [external_pointer]: The pointer to the external memory area backing this @@ -3655,7 +3653,6 @@ class Code: public HeapObject { inline Kind kind(); inline InlineCacheState ic_state(); // Only valid for IC stubs. inline ExtraICState extra_ic_state(); // Only valid for IC stubs. - inline InLoopFlag ic_in_loop(); // Only valid for IC stubs. inline PropertyType type(); // Only valid for monomorphic IC stubs. inline int arguments_count(); // Only valid for call IC stubs. @@ -3685,6 +3682,11 @@ class Code: public HeapObject { inline bool has_deoptimization_support(); inline void set_has_deoptimization_support(bool value); + // [has_debug_break_slots]: For FUNCTION kind, tells if it has + // been compiled with debug break slots. + inline bool has_debug_break_slots(); + inline void set_has_debug_break_slots(bool value); + // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for // how long the function has been marked for OSR and therefore which // level of loop nesting we are willing to do on-stack replacement @@ -3743,7 +3745,6 @@ class Code: public HeapObject { // Flags operations. static inline Flags ComputeFlags( Kind kind, - InLoopFlag in_loop = NOT_IN_LOOP, InlineCacheState ic_state = UNINITIALIZED, ExtraICState extra_ic_state = kNoExtraICState, PropertyType type = NORMAL, @@ -3755,16 +3756,15 @@ class Code: public HeapObject { PropertyType type, ExtraICState extra_ic_state = kNoExtraICState, InlineCacheHolderFlag holder = OWN_MAP, - InLoopFlag in_loop = NOT_IN_LOOP, int argc = -1); - static inline Kind ExtractKindFromFlags(Flags flags); static inline InlineCacheState ExtractICStateFromFlags(Flags flags); - static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags); - static inline InLoopFlag ExtractICInLoopFromFlags(Flags flags); static inline PropertyType ExtractTypeFromFlags(Flags flags); - static inline int ExtractArgumentsCountFromFlags(Flags flags); + static inline Kind ExtractKindFromFlags(Flags flags); static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags); + static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags); + static inline int ExtractArgumentsCountFromFlags(Flags flags); + static inline Flags RemoveTypeFromFlags(Flags flags); // Convert a target address into a code object. @@ -3875,34 +3875,32 @@ class Code: public HeapObject { static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1; static const int kCompareStateOffset = kStubMajorKeyOffset + 1; static const int kToBooleanTypeOffset = kStubMajorKeyOffset + 1; - static const int kHasDeoptimizationSupportOffset = kOptimizableOffset + 1; + + static const int kFullCodeFlags = kOptimizableOffset + 1; + class FullCodeFlagsHasDeoptimizationSupportField: + public BitField<bool, 0, 1> {}; // NOLINT + class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {}; static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1; - static const int kAllowOSRAtLoopNestingLevelOffset = - kHasDeoptimizationSupportOffset + 1; + + static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1; static const int kSafepointTableOffsetOffset = kStackSlotsOffset + kIntSize; static const int kStackCheckTableOffsetOffset = kStackSlotsOffset + kIntSize; - // Flags layout. - static const int kFlagsICStateShift = 0; - static const int kFlagsICInLoopShift = 3; - static const int kFlagsTypeShift = 4; - static const int kFlagsKindShift = 8; - static const int kFlagsICHolderShift = 12; - static const int kFlagsExtraICStateShift = 13; - static const int kFlagsArgumentsCountShift = 15; - - static const int kFlagsICStateMask = 0x00000007; // 00000000111 - static const int kFlagsICInLoopMask = 0x00000008; // 00000001000 - static const int kFlagsTypeMask = 0x000000F0; // 00001110000 - static const int kFlagsKindMask = 0x00000F00; // 11110000000 - static const int kFlagsCacheInPrototypeMapMask = 0x00001000; - static const int kFlagsExtraICStateMask = 0x00006000; - static const int kFlagsArgumentsCountMask = 0xFFFF8000; + // Flags layout. BitField<type, shift, size>. + class ICStateField: public BitField<InlineCacheState, 0, 3> {}; + class TypeField: public BitField<PropertyType, 3, 4> {}; + class KindField: public BitField<Kind, 7, 4> {}; + class CacheHolderField: public BitField<InlineCacheHolderFlag, 11, 1> {}; + class ExtraICStateField: public BitField<ExtraICState, 12, 2> {}; + + // Signed field cannot be encoded using the BitField class. + static const int kArgumentsCountShift = 14; + static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1); static const int kFlagsNotUsedInLookup = - (kFlagsICInLoopMask | kFlagsTypeMask | kFlagsCacheInPrototypeMapMask); + TypeField::kMask | CacheHolderField::kMask; private: DISALLOW_IMPLICIT_CONSTRUCTORS(Code); @@ -4021,37 +4019,37 @@ class Map: public HeapObject { inline void set_is_extensible(bool value); inline bool is_extensible(); - inline void set_elements_kind(JSObject::ElementsKind elements_kind) { - ASSERT(elements_kind < JSObject::kElementsKindCount); - ASSERT(JSObject::kElementsKindCount <= (1 << kElementsKindBitCount)); + inline void set_elements_kind(ElementsKind elements_kind) { + ASSERT(elements_kind < kElementsKindCount); + ASSERT(kElementsKindCount <= (1 << kElementsKindBitCount)); set_bit_field2((bit_field2() & ~kElementsKindMask) | (elements_kind << kElementsKindShift)); ASSERT(this->elements_kind() == elements_kind); } - inline JSObject::ElementsKind elements_kind() { - return static_cast<JSObject::ElementsKind>( + inline ElementsKind elements_kind() { + return static_cast<ElementsKind>( (bit_field2() & kElementsKindMask) >> kElementsKindShift); } // Tells whether the instance has fast elements. // Equivalent to instance->GetElementsKind() == FAST_ELEMENTS. inline bool has_fast_elements() { - return elements_kind() == JSObject::FAST_ELEMENTS; + return elements_kind() == FAST_ELEMENTS; } inline bool has_fast_double_elements() { - return elements_kind() == JSObject::FAST_DOUBLE_ELEMENTS; + return elements_kind() == FAST_DOUBLE_ELEMENTS; } inline bool has_external_array_elements() { - JSObject::ElementsKind kind(elements_kind()); - return kind >= JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && - kind <= JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND; + ElementsKind kind(elements_kind()); + return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && + kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND; } inline bool has_dictionary_elements() { - return elements_kind() == JSObject::DICTIONARY_ELEMENTS; + return elements_kind() == DICTIONARY_ELEMENTS; } // Tells whether the map is attached to SharedFunctionInfo @@ -4156,9 +4154,9 @@ class Map: public HeapObject { MUST_USE_RESULT inline MaybeObject* GetSlowElementsMap(); // Returns a new map with all transitions dropped from the descriptors and the - // ElementsKind set to one of the value corresponding to array_type. - MUST_USE_RESULT MaybeObject* GetExternalArrayElementsMap( - ExternalArrayType array_type, + // ElementsKind set. + MUST_USE_RESULT MaybeObject* GetElementsTransitionMap( + ElementsKind elements_kind, bool safe_to_add_transition); // Returns the property index for name (only valid for FAST MODE). @@ -4323,7 +4321,7 @@ class Map: public HeapObject { static const int kElementsKindMask = (-1 << kElementsKindShift) & ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1); static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>( - (JSObject::FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1; + (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1; // Bit positions for bit field 3 static const int kIsShared = 0; @@ -4737,7 +4735,7 @@ class SharedFunctionInfo: public HeapObject { DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters) // Indicates whether the function is a native function. - // These needs special threatment in .call and .apply since + // These needs special treatment in .call and .apply since // null passed as the receiver should not be translated to the // global object. DECL_BOOLEAN_ACCESSORS(native) @@ -5004,7 +5002,7 @@ class JSFunction: public JSObject { // [prototype_or_initial_map]: DECL_ACCESSORS(prototype_or_initial_map, Object) - // [shared_function_info]: The information about the function that + // [shared]: The information about the function that // can be shared by instances. DECL_ACCESSORS(shared, SharedFunctionInfo) @@ -5981,12 +5979,12 @@ class String: public HeapObject { // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it // handles unexpected data without causing assert failures and it does not // do any heap allocations. This is useful when printing stack traces. - SmartPointer<char> ToCString(AllowNullsFlag allow_nulls, - RobustnessFlag robustness_flag, - int offset, - int length, - int* length_output = 0); - SmartPointer<char> ToCString( + SmartArrayPointer<char> ToCString(AllowNullsFlag allow_nulls, + RobustnessFlag robustness_flag, + int offset, + int length, + int* length_output = 0); + SmartArrayPointer<char> ToCString( AllowNullsFlag allow_nulls = DISALLOW_NULLS, RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL, int* length_output = 0); @@ -5999,7 +5997,7 @@ class String: public HeapObject { // ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means it // handles unexpected data without causing assert failures and it does not // do any heap allocations. This is useful when printing stack traces. - SmartPointer<uc16> ToWideCString( + SmartArrayPointer<uc16> ToWideCString( RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL); // Tells whether the hash code has been computed. @@ -6409,7 +6407,6 @@ class ConsString: public String { // - truncating sliced string to enable otherwise unneeded parent to be GC'ed. class SlicedString: public String { public: - inline String* parent(); inline void set_parent(String* parent); inline int offset(); @@ -6722,9 +6719,6 @@ class JSProxy: public JSReceiver { // [handler]: The handler property. DECL_ACCESSORS(handler, Object) - // [padding]: The padding slot (unused, see below). - DECL_ACCESSORS(padding, Object) - // Casting. static inline JSProxy* cast(Object* obj); @@ -6748,6 +6742,9 @@ class JSProxy: public JSReceiver { // Turn this into an (empty) JSObject. void Fix(); + // Initializes the body after the handler slot. + inline void InitializeBody(int object_size, Object* value); + // Dispatched behavior. #ifdef OBJECT_PRINT inline void JSProxyPrint() { @@ -6764,9 +6761,11 @@ class JSProxy: public JSReceiver { // upon freeze. static const int kHandlerOffset = HeapObject::kHeaderSize; static const int kPaddingOffset = kHandlerOffset + kPointerSize; - static const int kSize = kPaddingOffset + kPointerSize; + static const int kSize = JSObject::kHeaderSize; + static const int kHeaderSize = kPaddingOffset; + static const int kPaddingSize = kSize - kPaddingOffset; - STATIC_CHECK(kSize == JSObject::kHeaderSize); + STATIC_CHECK(kPaddingSize >= 0); typedef FixedBodyDescriptor<kHandlerOffset, kHandlerOffset + kPointerSize, @@ -6777,12 +6776,41 @@ class JSProxy: public JSReceiver { }; -// TODO(rossberg): Only a stub for now. class JSFunctionProxy: public JSProxy { public: + // [call_trap]: The call trap. + DECL_ACCESSORS(call_trap, Object) + + // [construct_trap]: The construct trap. + DECL_ACCESSORS(construct_trap, Object) + // Casting. static inline JSFunctionProxy* cast(Object* obj); + // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void JSFunctionProxyPrint() { + JSFunctionProxyPrint(stdout); + } + void JSFunctionProxyPrint(FILE* out); +#endif +#ifdef DEBUG + void JSFunctionProxyVerify(); +#endif + + // Layout description. + static const int kCallTrapOffset = kHandlerOffset + kPointerSize; + static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize; + static const int kPaddingOffset = kConstructTrapOffset + kPointerSize; + static const int kSize = JSFunction::kSize; + static const int kPaddingSize = kSize - kPaddingOffset; + + STATIC_CHECK(kPaddingSize >= 0); + + typedef FixedBodyDescriptor<kHandlerOffset, + kConstructTrapOffset + kPointerSize, + kSize> BodyDescriptor; + private: DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy); }; diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc index d64e7b7600..e8d1810616 100644 --- a/deps/v8/src/parser.cc +++ b/deps/v8/src/parser.cc @@ -1369,7 +1369,7 @@ VariableProxy* Parser::Declare(Handle<String> name, if (harmony_block_scoping_) { // In harmony mode we treat re-declarations as early errors. See // ES5 16 for a definition of early errors. - SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); + SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); const char* elms[2] = { "Variable", *c_string }; Vector<const char*> args(elms, 2); ReportMessage("redeclaration", args); @@ -1902,7 +1902,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, // structured. However, these are probably changes we want to // make later anyway so we should go back and fix this then. if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { - SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS); + SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS); const char* elms[2] = { "Label", *c_string }; Vector<const char*> args(elms, 2); ReportMessage("redeclaration", args); @@ -3006,7 +3006,7 @@ void Parser::ReportUnexpectedToken(Token::Value token) { void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { - SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); + SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); const char* element[1] = { *name_string }; ReportMessage("invalid_preparser_data", Vector<const char*>(element, 1)); @@ -4096,7 +4096,7 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { // In harmony mode we treat conflicting variable bindinds as early // errors. See ES5 16 for a definition of early errors. Handle<String> name = decl->proxy()->name(); - SmartPointer<char> c_string = name->ToCString(DISALLOW_NULLS); + SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); const char* elms[2] = { "Variable", *c_string }; Vector<const char*> args(elms, 2); int position = decl->proxy()->position(); diff --git a/deps/v8/src/platform-cygwin.cc b/deps/v8/src/platform-cygwin.cc index 85a5e4f610..a72f5da4b7 100644 --- a/deps/v8/src/platform-cygwin.cc +++ b/deps/v8/src/platform-cygwin.cc @@ -474,7 +474,6 @@ void Thread::YieldCPU() { class CygwinMutex : public Mutex { public: - CygwinMutex() { pthread_mutexattr_t attrs; memset(&attrs, 0, sizeof(attrs)); diff --git a/deps/v8/src/platform-freebsd.cc b/deps/v8/src/platform-freebsd.cc index 9d9f1b795a..685ec3c786 100644 --- a/deps/v8/src/platform-freebsd.cc +++ b/deps/v8/src/platform-freebsd.cc @@ -471,7 +471,6 @@ void Thread::YieldCPU() { class FreeBSDMutex : public Mutex { public: - FreeBSDMutex() { pthread_mutexattr_t attrs; int result = pthread_mutexattr_init(&attrs); diff --git a/deps/v8/src/platform-macos.cc b/deps/v8/src/platform-macos.cc index be6e1572dc..6be941a08b 100644 --- a/deps/v8/src/platform-macos.cc +++ b/deps/v8/src/platform-macos.cc @@ -558,7 +558,6 @@ void Thread::YieldCPU() { class MacOSMutex : public Mutex { public: - MacOSMutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); diff --git a/deps/v8/src/platform-solaris.cc b/deps/v8/src/platform-solaris.cc index 1e79f102f5..035d394453 100644 --- a/deps/v8/src/platform-solaris.cc +++ b/deps/v8/src/platform-solaris.cc @@ -460,7 +460,6 @@ void Thread::YieldCPU() { class SolarisMutex : public Mutex { public: - SolarisMutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); diff --git a/deps/v8/src/platform-win32.cc b/deps/v8/src/platform-win32.cc index 4da0101eae..97788e2f66 100644 --- a/deps/v8/src/platform-win32.cc +++ b/deps/v8/src/platform-win32.cc @@ -1299,7 +1299,7 @@ int OS::StackWalk(Vector<OS::StackFrame> frames) { // Try to locate a symbol for this frame. DWORD64 symbol_displacement; - SmartPointer<IMAGEHLP_SYMBOL64> symbol( + SmartArrayPointer<IMAGEHLP_SYMBOL64> symbol( NewArray<IMAGEHLP_SYMBOL64>(kStackWalkMaxNameLen)); if (symbol.is_empty()) return kStackWalkError; // Out of memory. memset(*symbol, 0, sizeof(IMAGEHLP_SYMBOL64) + kStackWalkMaxNameLen); diff --git a/deps/v8/src/prettyprinter.cc b/deps/v8/src/prettyprinter.cc index 36860a36f9..663af284b4 100644 --- a/deps/v8/src/prettyprinter.cc +++ b/deps/v8/src/prettyprinter.cc @@ -633,17 +633,14 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info, void AstPrinter::PrintLabelsIndented(const char* info, ZoneStringList* labels) { if (labels != NULL && labels->length() > 0) { - if (info == NULL) { - PrintIndented("LABELS "); - } else { - PrintIndented(info); - Print(" "); - } + PrintIndented(info == NULL ? "LABELS" : info); + Print(" "); PrintLabels(labels); + Print("\n"); } else if (info != NULL) { PrintIndented(info); + Print("\n"); } - Print("\n"); } @@ -929,25 +926,25 @@ void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) { void AstPrinter::VisitVariableProxy(VariableProxy* node) { Variable* var = node->var(); - PrintLiteralWithModeIndented("VAR PROXY", var, node->name()); - { IndentedScope indent(this); - switch (var->location()) { - case Variable::UNALLOCATED: - break; - case Variable::PARAMETER: - Print("parameter[%d]", var->index()); - break; - case Variable::LOCAL: - Print("local[%d]", var->index()); - break; - case Variable::CONTEXT: - Print("context[%d]", var->index()); - break; - case Variable::LOOKUP: - Print("lookup"); - break; - } + EmbeddedVector<char, 128> buf; + int pos = OS::SNPrintF(buf, "VAR PROXY"); + switch (var->location()) { + case Variable::UNALLOCATED: + break; + case Variable::PARAMETER: + OS::SNPrintF(buf + pos, " parameter[%d]", var->index()); + break; + case Variable::LOCAL: + OS::SNPrintF(buf + pos, " local[%d]", var->index()); + break; + case Variable::CONTEXT: + OS::SNPrintF(buf + pos, " context[%d]", var->index()); + break; + case Variable::LOOKUP: + OS::SNPrintF(buf + pos, " lookup"); + break; } + PrintLiteralWithModeIndented(buf.start(), var, node->name()); } @@ -1105,7 +1102,7 @@ void JsonAstBuilder::AddAttributePrefix(const char* name) { void JsonAstBuilder::AddAttribute(const char* name, Handle<String> value) { - SmartPointer<char> value_string = value->ToCString(); + SmartArrayPointer<char> value_string = value->ToCString(); AddAttributePrefix(name); Print("\"%s\"", *value_string); } diff --git a/deps/v8/src/profile-generator-inl.h b/deps/v8/src/profile-generator-inl.h index 8f4bc6c1f2..88d6e87941 100644 --- a/deps/v8/src/profile-generator-inl.h +++ b/deps/v8/src/profile-generator-inl.h @@ -78,22 +78,6 @@ ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry) } -void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) { - CodeTree::Locator locator; - tree_.Insert(addr, &locator); - locator.set_value(CodeEntryInfo(entry, size)); -} - - -void CodeMap::MoveCode(Address from, Address to) { - tree_.Move(from, to); -} - -void CodeMap::DeleteCode(Address addr) { - tree_.Remove(addr); -} - - CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) { switch (tag) { case GC: diff --git a/deps/v8/src/profile-generator.cc b/deps/v8/src/profile-generator.cc index 74dfbf445c..a7384a62aa 100644 --- a/deps/v8/src/profile-generator.cc +++ b/deps/v8/src/profile-generator.cc @@ -492,6 +492,28 @@ const CodeMap::CodeTreeConfig::Value CodeMap::CodeTreeConfig::kNoValue = CodeMap::CodeEntryInfo(NULL, 0); +void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) { + DeleteAllCoveredCode(addr, addr + size); + CodeTree::Locator locator; + tree_.Insert(addr, &locator); + locator.set_value(CodeEntryInfo(entry, size)); +} + + +void CodeMap::DeleteAllCoveredCode(Address start, Address end) { + List<Address> to_delete; + Address addr = end - 1; + while (addr >= start) { + CodeTree::Locator locator; + if (!tree_.FindGreatestLessThan(addr, &locator)) break; + Address start2 = locator.key(), end2 = start2 + locator.value().size; + if (start2 < end && start < end2) to_delete.Add(start2); + addr = start2 - 1; + } + for (int i = 0; i < to_delete.length(); ++i) tree_.Remove(to_delete[i]); +} + + CodeEntry* CodeMap::FindEntry(Address addr) { CodeTree::Locator locator; if (tree_.FindGreatestLessThan(addr, &locator)) { @@ -520,6 +542,16 @@ int CodeMap::GetSharedId(Address addr) { } +void CodeMap::MoveCode(Address from, Address to) { + if (from == to) return; + CodeTree::Locator locator; + if (!tree_.Find(from, &locator)) return; + CodeEntryInfo entry = locator.value(); + tree_.Remove(from); + AddCode(to, entry.entry, entry.size); +} + + void CodeMap::CodeTreePrinter::Call( const Address& key, const CodeMap::CodeEntryInfo& value) { OS::Print("%p %5d %s\n", key, value.size, value.entry->name()); diff --git a/deps/v8/src/profile-generator.h b/deps/v8/src/profile-generator.h index 6bada36d57..f3737eafb9 100644 --- a/deps/v8/src/profile-generator.h +++ b/deps/v8/src/profile-generator.h @@ -238,9 +238,8 @@ class CpuProfile { class CodeMap { public: CodeMap() : next_shared_id_(1) { } - INLINE(void AddCode(Address addr, CodeEntry* entry, unsigned size)); - INLINE(void MoveCode(Address from, Address to)); - INLINE(void DeleteCode(Address addr)); + void AddCode(Address addr, CodeEntry* entry, unsigned size); + void MoveCode(Address from, Address to); CodeEntry* FindEntry(Address addr); int GetSharedId(Address addr); @@ -270,6 +269,8 @@ class CodeMap { void Call(const Address& key, const CodeEntryInfo& value); }; + void DeleteAllCoveredCode(Address start, Address end); + // Fake CodeEntry pointer to distinguish shared function entries. static CodeEntry* const kSharedFunctionCodeEntry; diff --git a/deps/v8/src/property.cc b/deps/v8/src/property.cc index dd232093bd..7cc2df5a3c 100644 --- a/deps/v8/src/property.cc +++ b/deps/v8/src/property.cc @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -52,8 +52,8 @@ void LookupResult::Print(FILE* out) { GetTransitionMap()->Print(out); PrintF(out, "\n"); break; - case EXTERNAL_ARRAY_TRANSITION: - PrintF(out, " -type = external array transition\n"); + case ELEMENTS_TRANSITION: + PrintF(out, " -type = elements transition\n"); PrintF(out, " -map:\n"); GetTransitionMap()->Print(out); PrintF(out, "\n"); diff --git a/deps/v8/src/property.h b/deps/v8/src/property.h index ddecc92198..e7d9fc5345 100644 --- a/deps/v8/src/property.h +++ b/deps/v8/src/property.h @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -112,14 +112,14 @@ class MapTransitionDescriptor: public Descriptor { : Descriptor(key, map, attributes, MAP_TRANSITION) { } }; -class ExternalArrayTransitionDescriptor: public Descriptor { +class ElementsTransitionDescriptor: public Descriptor { public: - ExternalArrayTransitionDescriptor(String* key, - Map* map, - ExternalArrayType array_type) + ElementsTransitionDescriptor(String* key, + Map* map, + ElementsKind elements_kind) : Descriptor(key, map, PropertyDetails(NONE, - EXTERNAL_ARRAY_TRANSITION, - array_type)) { } + ELEMENTS_TRANSITION, + elements_kind)) { } }; // Marks a field name in a map so that adding the field is guaranteed @@ -281,7 +281,7 @@ class LookupResult BASE_EMBEDDED { Map* GetTransitionMap() { ASSERT(lookup_type_ == DESCRIPTOR_TYPE); ASSERT(type() == MAP_TRANSITION || type() == CONSTANT_TRANSITION || - type() == EXTERNAL_ARRAY_TRANSITION); + type() == ELEMENTS_TRANSITION); return Map::cast(GetValue()); } diff --git a/deps/v8/src/proxy.js b/deps/v8/src/proxy.js index 2839159563..4e44cd4ef3 100644 --- a/deps/v8/src/proxy.js +++ b/deps/v8/src/proxy.js @@ -29,36 +29,6 @@ global.Proxy = new $Object(); var $Proxy = global.Proxy -var fundamentalTraps = [ - "getOwnPropertyDescriptor", - "getPropertyDescriptor", - "getOwnPropertyNames", - "getPropertyNames", - "defineProperty", - "delete", - "fix", -] - -var derivedTraps = [ - "has", - "hasOwn", - "get", - "set", - "enumerate", - "keys", -] - -var functionTraps = [ - "callTrap", - "constructTrap", -] - -$Proxy.createFunction = function(handler, callTrap, constructTrap) { - handler.callTrap = callTrap - handler.constructTrap = constructTrap - $Proxy.create(handler) -} - $Proxy.create = function(handler, proto) { if (!IS_SPEC_OBJECT(handler)) throw MakeTypeError("handler_non_object", ["create"]) @@ -66,6 +36,20 @@ $Proxy.create = function(handler, proto) { return %CreateJSProxy(handler, proto) } +$Proxy.createFunction = function(handler, callTrap, constructTrap) { + if (!IS_SPEC_OBJECT(handler)) + throw MakeTypeError("handler_non_object", ["create"]) + if (!IS_SPEC_FUNCTION(callTrap)) + throw MakeTypeError("trap_function_expected", ["createFunction", "call"]) + if (IS_UNDEFINED(constructTrap)) { + constructTrap = callTrap + } else if (!IS_SPEC_FUNCTION(constructTrap)) { + throw MakeTypeError("trap_function_expected", + ["createFunction", "construct"]) + } + return %CreateJSFunctionProxy( + handler, callTrap, constructTrap, $Function.prototype) +} @@ -73,6 +57,13 @@ $Proxy.create = function(handler, proto) { // Builtins //////////////////////////////////////////////////////////////////////////////// +function DelegateCallAndConstruct(callTrap, constructTrap) { + return function() { + return %Apply(%_IsConstructCall() ? constructTrap : callTrap, + this, arguments, 0, %_ArgumentsLength()) + } +} + function DerivedGetTrap(receiver, name) { var desc = this.getPropertyDescriptor(name) if (IS_UNDEFINED(desc)) { return desc } diff --git a/deps/v8/src/regexp-macro-assembler-irregexp.h b/deps/v8/src/regexp-macro-assembler-irregexp.h index 75cf8bf974..262ead297c 100644 --- a/deps/v8/src/regexp-macro-assembler-irregexp.h +++ b/deps/v8/src/regexp-macro-assembler-irregexp.h @@ -107,6 +107,7 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler { virtual IrregexpImplementation Implementation(); virtual Handle<HeapObject> GetCode(Handle<String> source); + private: void Expand(); // Code and bitmap emission. diff --git a/deps/v8/src/regexp-macro-assembler-tracer.h b/deps/v8/src/regexp-macro-assembler-tracer.h index 8c6cf3ab61..1cf0349d86 100644 --- a/deps/v8/src/regexp-macro-assembler-tracer.h +++ b/deps/v8/src/regexp-macro-assembler-tracer.h @@ -95,6 +95,7 @@ class RegExpMacroAssemblerTracer: public RegExpMacroAssembler { virtual void WriteCurrentPositionToRegister(int reg, int cp_offset); virtual void ClearRegisters(int reg_from, int reg_to); virtual void WriteStackPointerToRegister(int reg); + private: RegExpMacroAssembler* assembler_; }; diff --git a/deps/v8/src/regexp-stack.h b/deps/v8/src/regexp-stack.h index 59432067e4..5684239f9f 100644 --- a/deps/v8/src/regexp-stack.h +++ b/deps/v8/src/regexp-stack.h @@ -89,6 +89,7 @@ class RegExpStack { char* ArchiveStack(char* to); char* RestoreStack(char* from); void FreeThreadResources() { thread_local_.Free(); } + private: RegExpStack(); ~RegExpStack(); diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc index 95a24f0ef2..3ea93049c0 100644 --- a/deps/v8/src/runtime.cc +++ b/deps/v8/src/runtime.cc @@ -52,7 +52,7 @@ #include "runtime-profiler.h" #include "runtime.h" #include "scopeinfo.h" -#include "smart-pointer.h" +#include "smart-array-pointer.h" #include "string-search.h" #include "stub-cache.h" #include "v8threads.h" @@ -177,7 +177,7 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate, // Pixel elements cannot be created using an object literal. ASSERT(!copy->HasExternalArrayElements()); switch (copy->GetElementsKind()) { - case JSObject::FAST_ELEMENTS: { + case FAST_ELEMENTS: { FixedArray* elements = FixedArray::cast(copy->elements()); if (elements->map() == heap->fixed_cow_array_map()) { isolate->counters()->cow_arrays_created_runtime()->Increment(); @@ -201,7 +201,7 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate, } break; } - case JSObject::DICTIONARY_ELEMENTS: { + case DICTIONARY_ELEMENTS: { NumberDictionary* element_dictionary = copy->element_dictionary(); int capacity = element_dictionary->Capacity(); for (int i = 0; i < capacity; i++) { @@ -220,19 +220,19 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate, } break; } - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNIMPLEMENTED(); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: // No contained objects, nothing to do. break; } @@ -613,6 +613,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) { } +RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) { + ASSERT(args.length() == 4); + Object* handler = args[0]; + Object* call_trap = args[1]; + Object* construct_trap = args[2]; + Object* prototype = args[3]; + Object* used_prototype = + prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value(); + return isolate->heap()->AllocateJSFunctionProxy( + handler, call_trap, construct_trap, used_prototype); +} + + RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) { ASSERT(args.length() == 1); Object* obj = args[0]; @@ -620,6 +633,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) { } +RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) { + ASSERT(args.length() == 1); + Object* obj = args[0]; + return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy()); +} + + RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { ASSERT(args.length() == 1); CONVERT_CHECKED(JSProxy, proxy, args[0]); @@ -627,6 +647,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { } +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) { + ASSERT(args.length() == 1); + CONVERT_CHECKED(JSFunctionProxy, proxy, args[0]); + return proxy->call_trap(); +} + + +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) { + ASSERT(args.length() == 1); + CONVERT_CHECKED(JSFunctionProxy, proxy, args[0]); + return proxy->construct_trap(); +} + + RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { ASSERT(args.length() == 1); CONVERT_CHECKED(JSProxy, proxy, args[0]); @@ -2154,7 +2188,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) { RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) { - RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); HandleScope scope(isolate); ASSERT(args.length() == 2); @@ -2210,6 +2243,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) { // are guaranteed to be in old space. target->set_literals(*literals, SKIP_WRITE_BARRIER); target->set_next_function_link(isolate->heap()->undefined_value()); + + if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) { + isolate->logger()->LogExistingFunction( + shared, Handle<Code>(shared->code())); + } } target->set_context(*context); @@ -4293,6 +4331,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { if (proto->IsNull()) return *obj_value; js_object = Handle<JSObject>::cast(proto); } + + // Don't allow element properties to be redefined on objects with external + // array elements. + if (js_object->HasExternalArrayElements()) { + Handle<Object> args[2] = { js_object, name }; + Handle<Object> error = + isolate->factory()->NewTypeError("redef_external_array_element", + HandleVector(args, 2)); + return isolate->Throw(*error); + } + Handle<NumberDictionary> dictionary = NormalizeElements(js_object); // Make sure that we never go back to fast case. dictionary->set_requires_slow_elements(); @@ -4300,8 +4349,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { Handle<NumberDictionary> extended_dictionary = NumberDictionarySet(dictionary, index, obj_value, details); if (*extended_dictionary != *dictionary) { - if (js_object->GetElementsKind() == - JSObject::NON_STRICT_ARGUMENTS_ELEMENTS) { + if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); } else { js_object->set_elements(*extended_dictionary); @@ -5091,6 +5139,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) { ASSERT(heap_obj->IsUndefined()); return isolate->heap()->undefined_symbol(); case JS_FUNCTION_TYPE: + case JS_FUNCTION_PROXY_TYPE: return isolate->heap()->function_symbol(); default: // For any kind of object not handled above, the spec rule for @@ -7770,7 +7819,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { Handle<Map> old_map(result->map()); Handle<Map> new_map = isolate->factory()->CopyMapDropTransitions(old_map); - new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); + new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS); result->set_map(*new_map); result->set_elements(*parameter_map); @@ -7898,8 +7947,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) { } -static SmartPointer<Object**> GetNonBoundArguments(int bound_argc, - int* total_argc) { +static SmartArrayPointer<Object**> GetNonBoundArguments(int bound_argc, + int* total_argc) { // Find frame containing arguments passed to the caller. JavaScriptFrameIterator it; JavaScriptFrame* frame = it.frame(); @@ -7915,7 +7964,7 @@ static SmartPointer<Object**> GetNonBoundArguments(int bound_argc, &args_slots); *total_argc = bound_argc + args_count; - SmartPointer<Object**> param_data(NewArray<Object**>(*total_argc)); + SmartArrayPointer<Object**> param_data(NewArray<Object**>(*total_argc)); for (int i = 0; i < args_count; i++) { Handle<Object> val = args_slots[i].GetValue(); param_data[bound_argc + i] = val.location(); @@ -7927,7 +7976,7 @@ static SmartPointer<Object**> GetNonBoundArguments(int bound_argc, int args_count = frame->ComputeParametersCount(); *total_argc = bound_argc + args_count; - SmartPointer<Object**> param_data(NewArray<Object**>(*total_argc)); + SmartArrayPointer<Object**> param_data(NewArray<Object**>(*total_argc)); for (int i = 0; i < args_count; i++) { Handle<Object> val = Handle<Object>(frame->GetParameter(i)); param_data[bound_argc + i] = val.location(); @@ -7954,7 +8003,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) { } int total_argc = 0; - SmartPointer<Object**> param_data = + SmartArrayPointer<Object**> param_data = GetNonBoundArguments(bound_argc, &total_argc); for (int i = 0; i < bound_argc; i++) { Handle<Object> val = Handle<Object>(bound_args->get(i)); @@ -8095,15 +8144,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) { } #endif - // Compile the target function. Here we compile using CompileLazyInLoop in - // order to get the optimized version. This helps code like delta-blue - // that calls performance-critical routines through constructors. A - // constructor call doesn't use a CallIC, it uses a LoadIC followed by a - // direct call. Since the in-loop tracking takes place through CallICs - // this means that things called through constructors are never known to - // be in loops. We compile them as if they are in loops here just in case. + // Compile the target function. ASSERT(!function->is_compiled()); - if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { + if (!CompileLazy(function, KEEP_EXCEPTION)) { return Failure::Exception(); } @@ -8117,6 +8160,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) { HandleScope scope(isolate); ASSERT(args.length() == 1); Handle<JSFunction> function = args.at<JSFunction>(0); + + // If the function is not compiled ignore the lazy + // recompilation. This can happen if the debugger is activated and + // the function is returned to the not compiled state. + if (!function->shared()->is_compiled()) { + function->ReplaceCode(function->shared()->code()); + return function->code(); + } + // If the function is not optimizable or debugger is active continue using the // code from the full compiler. if (!function->shared()->code()->optimizable() || @@ -8182,8 +8234,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { if (type == Deoptimizer::EAGER) { RUNTIME_ASSERT(function->IsOptimized()); - } else { - RUNTIME_ASSERT(!function->IsOptimized()); } // Avoid doing too much work when running with --always-opt and keep @@ -8202,8 +8252,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { it.Advance(); } - // TODO(kasperl): For now, we cannot support removing the optimized - // code when we have recursive invocations of the same function. if (activations == 0) { if (FLAG_trace_deopt) { PrintF("[removing optimized code for: "); @@ -8211,6 +8259,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { PrintF("]\n"); } function->ReplaceCode(function->shared()->code()); + } else { + Deoptimizer::DeoptimizeFunction(*function); } return isolate->heap()->undefined_value(); } @@ -8397,6 +8447,49 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) { } +RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) { + HandleScope scope(isolate); + ASSERT(args.length() == 5); + CONVERT_CHECKED(JSReceiver, fun, args[0]); + Object* receiver = args[1]; + CONVERT_CHECKED(JSObject, arguments, args[2]); + CONVERT_CHECKED(Smi, shift, args[3]); + CONVERT_CHECKED(Smi, arity, args[4]); + + int offset = shift->value(); + int argc = arity->value(); + ASSERT(offset >= 0); + ASSERT(argc >= 0); + + // If there are too many arguments, allocate argv via malloc. + const int argv_small_size = 10; + Handle<Object> argv_small_buffer[argv_small_size]; + SmartArrayPointer<Handle<Object> > argv_large_buffer; + Handle<Object>* argv = argv_small_buffer; + if (argc > argv_small_size) { + argv = new Handle<Object>[argc]; + if (argv == NULL) return isolate->StackOverflow(); + argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); + } + + for (int i = 0; i < argc; ++i) { + MaybeObject* maybe = arguments->GetElement(offset + i); + Object* object; + if (!maybe->To<Object>(&object)) return maybe; + argv[i] = Handle<Object>(object); + } + + bool threw = false; + Handle<JSReceiver> hfun(fun); + Handle<Object> hreceiver(receiver); + Handle<Object> result = Execution::Call( + hfun, hreceiver, argc, reinterpret_cast<Object***>(argv), &threw, true); + + if (threw) return Failure::Exception(); + return *result; +} + + RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) { HandleScope scope(isolate); ASSERT(args.length() == 1); @@ -8873,7 +8966,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StackGuard) { static void PrintString(String* str) { // not uncommon to have empty strings if (str->length() > 0) { - SmartPointer<char> s = + SmartArrayPointer<char> s = str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); PrintF("%s", *s); } @@ -9468,7 +9561,7 @@ static uint32_t EstimateElementCount(Handle<JSArray> array) { uint32_t length = static_cast<uint32_t>(array->length()->Number()); int element_count = 0; switch (array->GetElementsKind()) { - case JSObject::FAST_ELEMENTS: { + case FAST_ELEMENTS: { // Fast elements can't have lengths that are not representable by // a 32-bit signed integer. ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); @@ -9479,7 +9572,7 @@ static uint32_t EstimateElementCount(Handle<JSArray> array) { } break; } - case JSObject::DICTIONARY_ELEMENTS: { + case DICTIONARY_ELEMENTS: { Handle<NumberDictionary> dictionary( NumberDictionary::cast(array->elements())); int capacity = dictionary->Capacity(); @@ -9555,9 +9648,9 @@ static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { static void CollectElementIndices(Handle<JSObject> object, uint32_t range, List<uint32_t>* indices) { - JSObject::ElementsKind kind = object->GetElementsKind(); + ElementsKind kind = object->GetElementsKind(); switch (kind) { - case JSObject::FAST_ELEMENTS: { + case FAST_ELEMENTS: { Handle<FixedArray> elements(FixedArray::cast(object->elements())); uint32_t length = static_cast<uint32_t>(elements->length()); if (range < length) length = range; @@ -9568,7 +9661,7 @@ static void CollectElementIndices(Handle<JSObject> object, } break; } - case JSObject::DICTIONARY_ELEMENTS: { + case DICTIONARY_ELEMENTS: { Handle<NumberDictionary> dict(NumberDictionary::cast(object->elements())); uint32_t capacity = dict->Capacity(); for (uint32_t j = 0; j < capacity; j++) { @@ -9587,47 +9680,47 @@ static void CollectElementIndices(Handle<JSObject> object, default: { int dense_elements_length; switch (kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: { + case EXTERNAL_PIXEL_ELEMENTS: { dense_elements_length = ExternalPixelArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_BYTE_ELEMENTS: { + case EXTERNAL_BYTE_ELEMENTS: { dense_elements_length = ExternalByteArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { dense_elements_length = ExternalUnsignedByteArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_SHORT_ELEMENTS: { + case EXTERNAL_SHORT_ELEMENTS: { dense_elements_length = ExternalShortArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { dense_elements_length = ExternalUnsignedShortArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_INT_ELEMENTS: { + case EXTERNAL_INT_ELEMENTS: { dense_elements_length = ExternalIntArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { + case EXTERNAL_UNSIGNED_INT_ELEMENTS: { dense_elements_length = ExternalUnsignedIntArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_FLOAT_ELEMENTS: { + case EXTERNAL_FLOAT_ELEMENTS: { dense_elements_length = ExternalFloatArray::cast(object->elements())->length(); break; } - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: { + case EXTERNAL_DOUBLE_ELEMENTS: { dense_elements_length = ExternalDoubleArray::cast(object->elements())->length(); break; @@ -9676,7 +9769,7 @@ static bool IterateElements(Isolate* isolate, ArrayConcatVisitor* visitor) { uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); switch (receiver->GetElementsKind()) { - case JSObject::FAST_ELEMENTS: { + case FAST_ELEMENTS: { // Run through the elements FixedArray and use HasElement and GetElement // to check the prototype for missing elements. Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); @@ -9697,7 +9790,7 @@ static bool IterateElements(Isolate* isolate, } break; } - case JSObject::DICTIONARY_ELEMENTS: { + case DICTIONARY_ELEMENTS: { Handle<NumberDictionary> dict(receiver->element_dictionary()); List<uint32_t> indices(dict->Capacity() / 2); // Collect all indices in the object and the prototypes less @@ -9719,7 +9812,7 @@ static bool IterateElements(Isolate* isolate, } break; } - case JSObject::EXTERNAL_PIXEL_ELEMENTS: { + case EXTERNAL_PIXEL_ELEMENTS: { Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast( receiver->elements())); for (uint32_t j = 0; j < length; j++) { @@ -9728,42 +9821,42 @@ static bool IterateElements(Isolate* isolate, } break; } - case JSObject::EXTERNAL_BYTE_ELEMENTS: { + case EXTERNAL_BYTE_ELEMENTS: { IterateExternalArrayElements<ExternalByteArray, int8_t>( isolate, receiver, true, true, visitor); break; } - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>( isolate, receiver, true, true, visitor); break; } - case JSObject::EXTERNAL_SHORT_ELEMENTS: { + case EXTERNAL_SHORT_ELEMENTS: { IterateExternalArrayElements<ExternalShortArray, int16_t>( isolate, receiver, true, true, visitor); break; } - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>( isolate, receiver, true, true, visitor); break; } - case JSObject::EXTERNAL_INT_ELEMENTS: { + case EXTERNAL_INT_ELEMENTS: { IterateExternalArrayElements<ExternalIntArray, int32_t>( isolate, receiver, true, false, visitor); break; } - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { + case EXTERNAL_UNSIGNED_INT_ELEMENTS: { IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>( isolate, receiver, true, false, visitor); break; } - case JSObject::EXTERNAL_FLOAT_ELEMENTS: { + case EXTERNAL_FLOAT_ELEMENTS: { IterateExternalArrayElements<ExternalFloatArray, float>( isolate, receiver, false, false, visitor); break; } - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: { + case EXTERNAL_DOUBLE_ELEMENTS: { IterateExternalArrayElements<ExternalDoubleArray, double>( isolate, receiver, false, false, visitor); break; @@ -10135,7 +10228,7 @@ static MaybeObject* DebugLookupResultValue(Heap* heap, } case INTERCEPTOR: case MAP_TRANSITION: - case EXTERNAL_ARRAY_TRANSITION: + case ELEMENTS_TRANSITION: case CONSTANT_TRANSITION: case NULL_DESCRIPTOR: return heap->undefined_value(); @@ -10941,15 +11034,16 @@ class ScopeIterator { at_local_(false) { // Check whether the first scope is actually a local scope. - if (context_->IsGlobalContext()) { - // If there is a stack slot for .result then this local scope has been - // created for evaluating top level code and it is not a real local scope. - // Checking for the existence of .result seems fragile, but the scope info - // saved with the code object does not otherwise have that information. - int index = function_->shared()->scope_info()-> - StackSlotIndex(isolate_->heap()->result_symbol()); - at_local_ = index < 0; - } else if (context_->IsFunctionContext()) { + // If there is a stack slot for .result then this local scope has been + // created for evaluating top level code and it is not a real local scope. + // Checking for the existence of .result seems fragile, but the scope info + // saved with the code object does not otherwise have that information. + int index = function_->shared()->scope_info()-> + StackSlotIndex(isolate_->heap()->result_symbol()); + if (index >= 0) { + local_done_ = true; + } else if (context_->IsGlobalContext() || + context_->IsFunctionContext()) { at_local_ = true; } else if (context_->closure() != *function_) { // The context_ is a block or with or catch block from the outer function. @@ -10996,7 +11090,7 @@ class ScopeIterator { } // Return the type of the current scope. - int Type() { + ScopeType Type() { if (at_local_) { return ScopeTypeLocal; } @@ -12425,7 +12519,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) { // Sets a v8 flag. RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) { CONVERT_CHECKED(String, arg, args[0]); - SmartPointer<char> flags = + SmartArrayPointer<char> flags = arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); FlagList::SetFlagsFromString(*flags, StrLength(*flags)); return isolate->heap()->undefined_value(); diff --git a/deps/v8/src/runtime.h b/deps/v8/src/runtime.h index ddd529588b..1538b7d846 100644 --- a/deps/v8/src/runtime.h +++ b/deps/v8/src/runtime.h @@ -80,6 +80,7 @@ namespace internal { \ /* Utilities */ \ F(CheckIsBootstrapping, 0, 1) \ + F(Apply, 5, 1) \ F(GetFunctionDelegate, 1, 1) \ F(GetConstructorDelegate, 1, 1) \ F(NewArgumentsFast, 3, 1) \ @@ -287,8 +288,12 @@ namespace internal { \ /* Harmony proxies */ \ F(CreateJSProxy, 2, 1) \ + F(CreateJSFunctionProxy, 4, 1) \ F(IsJSProxy, 1, 1) \ + F(IsJSFunctionProxy, 1, 1) \ F(GetHandler, 1, 1) \ + F(GetCallTrap, 1, 1) \ + F(GetConstructTrap, 1, 1) \ F(Fix, 1, 1) \ \ /* Harmony weakmaps */ \ diff --git a/deps/v8/src/runtime.js b/deps/v8/src/runtime.js index 61deb9baa0..14ff1b69cf 100644 --- a/deps/v8/src/runtime.js +++ b/deps/v8/src/runtime.js @@ -366,7 +366,7 @@ function IN(x) { // an expensive ToBoolean conversion in the generated code. function INSTANCE_OF(F) { var V = this; - if (!IS_FUNCTION(F)) { + if (!IS_SPEC_FUNCTION(F)) { throw %MakeTypeError('instanceof_function_expected', [V]); } @@ -408,7 +408,7 @@ function CALL_NON_FUNCTION() { if (!IS_FUNCTION(delegate)) { throw %MakeTypeError('called_non_callable', [typeof this]); } - return delegate.apply(this, arguments); + return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); } @@ -417,7 +417,32 @@ function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { if (!IS_FUNCTION(delegate)) { throw %MakeTypeError('called_non_callable', [typeof this]); } - return delegate.apply(this, arguments); + return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); +} + + +function CALL_FUNCTION_PROXY() { + var arity = %_ArgumentsLength() - 1; + var proxy = %_Arguments(arity); // The proxy comes in as an additional arg. + var trap = %GetCallTrap(proxy); + return %Apply(trap, this, arguments, 0, arity); +} + + +function CALL_FUNCTION_PROXY_AS_CONSTRUCTOR(proxy) { + var arity = %_ArgumentsLength() - 1; + var trap = %GetConstructTrap(proxy); + var receiver = void 0; + if (!IS_UNDEFINED(trap)) { + trap = %GetCallTrap(proxy); + var proto = proxy.prototype; + if (!IS_SPEC_OBJECT(proto) && proto !== null) { + throw MakeTypeError("proto_object_or_null", [proto]); + } + receiver = new global.Object(); + receiver.__proto__ = proto; + } + return %Apply(trap, this, arguments, 1, arity); } @@ -428,7 +453,8 @@ function APPLY_PREPARE(args) { // that takes care of more eventualities. if (IS_ARRAY(args)) { length = args.length; - if (%_IsSmi(length) && length >= 0 && length < 0x800000 && IS_FUNCTION(this)) { + if (%_IsSmi(length) && length >= 0 && length < 0x800000 && + IS_SPEC_FUNCTION(this)) { return length; } } @@ -442,7 +468,7 @@ function APPLY_PREPARE(args) { throw %MakeRangeError('stack_overflow', []); } - if (!IS_FUNCTION(this)) { + if (!IS_SPEC_FUNCTION(this)) { throw %MakeTypeError('apply_non_function', [ %ToString(this), typeof this ]); } @@ -610,13 +636,13 @@ function IsPrimitive(x) { // ECMA-262, section 8.6.2.6, page 28. function DefaultNumber(x) { var valueOf = x.valueOf; - if (IS_FUNCTION(valueOf)) { + if (IS_SPEC_FUNCTION(valueOf)) { var v = %_CallFunction(x, valueOf); if (%IsPrimitive(v)) return v; } var toString = x.toString; - if (IS_FUNCTION(toString)) { + if (IS_SPEC_FUNCTION(toString)) { var s = %_CallFunction(x, toString); if (%IsPrimitive(s)) return s; } @@ -628,13 +654,13 @@ function DefaultNumber(x) { // ECMA-262, section 8.6.2.6, page 28. function DefaultString(x) { var toString = x.toString; - if (IS_FUNCTION(toString)) { + if (IS_SPEC_FUNCTION(toString)) { var s = %_CallFunction(x, toString); if (%IsPrimitive(s)) return s; } var valueOf = x.valueOf; - if (IS_FUNCTION(valueOf)) { + if (IS_SPEC_FUNCTION(valueOf)) { var v = %_CallFunction(x, valueOf); if (%IsPrimitive(v)) return v; } diff --git a/deps/v8/src/safepoint-table.cc b/deps/v8/src/safepoint-table.cc index 28cf6e64c9..bcd0a1d63d 100644 --- a/deps/v8/src/safepoint-table.cc +++ b/deps/v8/src/safepoint-table.cc @@ -68,8 +68,8 @@ SafepointTable::SafepointTable(Code* code) { entries_ = pc_and_deoptimization_indexes_ + (length_ * kPcAndDeoptimizationIndexSize); ASSERT(entry_size_ > 0); - ASSERT_EQ(SafepointEntry::DeoptimizationIndexField::max(), - Safepoint::kNoDeoptimizationIndex); + STATIC_ASSERT(SafepointEntry::DeoptimizationIndexField::kMax == + Safepoint::kNoDeoptimizationIndex); } diff --git a/deps/v8/src/scanner-character-streams.cc b/deps/v8/src/scanner-character-streams.cc index 2c1ccea69e..ee10703c9e 100644 --- a/deps/v8/src/scanner-character-streams.cc +++ b/deps/v8/src/scanner-character-streams.cc @@ -29,7 +29,6 @@ #include "scanner-character-streams.h" -#include "ast.h" #include "handles.h" #include "unicode-inl.h" @@ -305,24 +304,4 @@ ExternalTwoByteStringUC16CharacterStream pos_ = start_position; } - -// ---------------------------------------------------------------------------- -// Scanner::LiteralScope - -Scanner::LiteralScope::LiteralScope(Scanner* self) - : scanner_(self), complete_(false) { - self->StartLiteral(); -} - - -Scanner::LiteralScope::~LiteralScope() { - if (!complete_) scanner_->DropLiteral(); -} - - -void Scanner::LiteralScope::Complete() { - scanner_->TerminateLiteral(); - complete_ = true; -} - } } // namespace v8::internal diff --git a/deps/v8/src/scanner.cc b/deps/v8/src/scanner.cc index 3425f4159e..69ea8ae6e7 100644 --- a/deps/v8/src/scanner.cc +++ b/deps/v8/src/scanner.cc @@ -36,6 +36,25 @@ namespace v8 { namespace internal { // ---------------------------------------------------------------------------- +// Scanner::LiteralScope + +Scanner::LiteralScope::LiteralScope(Scanner* self) + : scanner_(self), complete_(false) { + self->StartLiteral(); +} + + +Scanner::LiteralScope::~LiteralScope() { + if (!complete_) scanner_->DropLiteral(); +} + + +void Scanner::LiteralScope::Complete() { + scanner_->TerminateLiteral(); + complete_ = true; +} + +// ---------------------------------------------------------------------------- // Scanner Scanner::Scanner(UnicodeCache* unicode_cache) diff --git a/deps/v8/src/scanner.h b/deps/v8/src/scanner.h index 73a4e21798..16c3a427c9 100644 --- a/deps/v8/src/scanner.h +++ b/deps/v8/src/scanner.h @@ -135,7 +135,6 @@ class UnicodeCache { bool IsWhiteSpace(unibrow::uchar c) { return kIsWhiteSpace.get(c); } private: - unibrow::Predicate<IdentifierStart, 128> kIsIdentifierStart; unibrow::Predicate<IdentifierPart, 128> kIsIdentifierPart; unibrow::Predicate<unibrow::LineTerminator, 128> kIsLineTerminator; @@ -198,6 +197,7 @@ class LiteralBuffer { position_ = 0; is_ascii_ = true; } + private: static const int kInitialCapacity = 16; static const int kGrowthFactory = 4; diff --git a/deps/v8/src/scopeinfo.h b/deps/v8/src/scopeinfo.h index 1c61f1115d..40c5c8a687 100644 --- a/deps/v8/src/scopeinfo.h +++ b/deps/v8/src/scopeinfo.h @@ -156,7 +156,6 @@ class SerializedScopeInfo : public FixedArray { static SerializedScopeInfo* Empty(); private: - inline Object** ContextEntriesAddr(); inline Object** ParameterEntriesAddr(); @@ -187,6 +186,7 @@ class ContextSlotCache { void Clear(); static const int kNotFound = -2; + private: ContextSlotCache() { for (int i = 0; i < kLength; ++i) { diff --git a/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc index 4e87b25e11..d5a7a9f9ca 100644 --- a/deps/v8/src/scopes.cc +++ b/deps/v8/src/scopes.cc @@ -663,7 +663,7 @@ static void Indent(int n, const char* str) { static void PrintName(Handle<String> name) { - SmartPointer<char> s = name->ToCString(DISALLOW_NULLS); + SmartArrayPointer<char> s = name->ToCString(DISALLOW_NULLS); PrintF("%s", *s); } @@ -695,7 +695,7 @@ static void PrintVar(int indent, Variable* var) { PrintName(var->name()); PrintF("; // "); PrintLocation(var); - if (var->is_accessed_from_inner_function_scope()) { + if (var->is_accessed_from_inner_scope()) { if (!var->IsUnallocated()) PrintF(", "); PrintF("inner scope access"); } @@ -818,7 +818,7 @@ Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { // another variable that is introduced dynamically via an 'eval' call // or a 'with' statement). Variable* Scope::LookupRecursive(Handle<String> name, - bool from_inner_function, + bool from_inner_scope, Variable** invalidated_local) { // If we find a variable, but the current scope calls 'eval', the found // variable may not be the correct one (the 'eval' may introduce a @@ -834,7 +834,7 @@ Variable* Scope::LookupRecursive(Handle<String> name, // (Even if there is an 'eval' in this scope which introduces the // same variable again, the resulting variable remains the same. // Note that enclosing 'with' statements are handled at the call site.) - if (!from_inner_function) + if (!from_inner_scope) return var; } else { @@ -850,10 +850,7 @@ Variable* Scope::LookupRecursive(Handle<String> name, var = function_->var(); } else if (outer_scope_ != NULL) { - var = outer_scope_->LookupRecursive( - name, - is_function_scope() || from_inner_function, - invalidated_local); + var = outer_scope_->LookupRecursive(name, true, invalidated_local); // We may have found a variable in an outer scope. However, if // the current scope is inside a 'with', the actual variable may // be a property introduced via the 'with' statement. Then, the @@ -870,8 +867,8 @@ Variable* Scope::LookupRecursive(Handle<String> name, ASSERT(var != NULL); // If this is a lookup from an inner scope, mark the variable. - if (from_inner_function) { - var->MarkAsAccessedFromInnerFunctionScope(); + if (from_inner_scope) { + var->MarkAsAccessedFromInnerScope(); } // If the variable we have found is just a guess, invalidate the @@ -1022,7 +1019,7 @@ bool Scope::MustAllocate(Variable* var) { // via an eval() call. This is only possible if the variable has a // visible name. if ((var->is_this() || var->name()->length() > 0) && - (var->is_accessed_from_inner_function_scope() || + (var->is_accessed_from_inner_scope() || scope_calls_eval_ || inner_scope_calls_eval_ || scope_contains_with_ || @@ -1045,7 +1042,7 @@ bool Scope::MustAllocateInContext(Variable* var) { // catch-bound variables are always allocated in a context. if (var->mode() == Variable::TEMPORARY) return false; if (is_catch_scope() || is_block_scope()) return true; - return var->is_accessed_from_inner_function_scope() || + return var->is_accessed_from_inner_scope() || scope_calls_eval_ || inner_scope_calls_eval_ || scope_contains_with_ || @@ -1111,7 +1108,7 @@ void Scope::AllocateParameterLocals() { if (uses_nonstrict_arguments) { // Give the parameter a use from an inner scope, to force allocation // to the context. - var->MarkAsAccessedFromInnerFunctionScope(); + var->MarkAsAccessedFromInnerScope(); } if (MustAllocate(var)) { diff --git a/deps/v8/src/serialize.cc b/deps/v8/src/serialize.cc index 094ad20b22..ecb480a8f8 100644 --- a/deps/v8/src/serialize.cc +++ b/deps/v8/src/serialize.cc @@ -240,13 +240,14 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { // Top addresses const char* AddressNames[] = { -#define C(name) "Isolate::" #name, - ISOLATE_ADDRESS_LIST(C) +#define BUILD_NAME_LITERAL(CamelName, hacker_name) \ + "Isolate::" #hacker_name "_address", + FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL) NULL #undef C }; - for (uint16_t i = 0; i < Isolate::k_isolate_address_count; ++i) { + for (uint16_t i = 0; i < Isolate::kIsolateAddressCount; ++i) { Add(isolate->get_address_from_id((Isolate::AddressId)i), TOP_ADDRESS, i, AddressNames[i]); } diff --git a/deps/v8/src/smart-pointer.h b/deps/v8/src/smart-array-pointer.h index a3e930d81a..00721c1a02 100644 --- a/deps/v8/src/smart-pointer.h +++ b/deps/v8/src/smart-array-pointer.h @@ -1,4 +1,4 @@ -// Copyright 2008 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -25,8 +25,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef V8_SMART_POINTER_H_ -#define V8_SMART_POINTER_H_ +#ifndef V8_SMART_ARRAY_POINTER_H_ +#define V8_SMART_ARRAY_POINTER_H_ namespace v8 { namespace internal { @@ -35,24 +35,24 @@ namespace internal { // A 'scoped array pointer' that calls DeleteArray on its pointer when the // destructor is called. template<typename T> -class SmartPointer { +class SmartArrayPointer { public: // Default constructor. Constructs an empty scoped pointer. - inline SmartPointer() : p_(NULL) {} + inline SmartArrayPointer() : p_(NULL) {} // Constructs a scoped pointer from a plain one. - explicit inline SmartPointer(T* ptr) : p_(ptr) {} + explicit inline SmartArrayPointer(T* ptr) : p_(ptr) {} // Copy constructor removes the pointer from the original to avoid double // freeing. - inline SmartPointer(const SmartPointer<T>& rhs) : p_(rhs.p_) { - const_cast<SmartPointer<T>&>(rhs).p_ = NULL; + inline SmartArrayPointer(const SmartArrayPointer<T>& rhs) : p_(rhs.p_) { + const_cast<SmartArrayPointer<T>&>(rhs).p_ = NULL; } // When the destructor of the scoped pointer is executed the plain pointer // is deleted using DeleteArray. This implies that you must allocate with // NewArray. - inline ~SmartPointer() { if (p_) DeleteArray(p_); } + inline ~SmartArrayPointer() { if (p_) DeleteArray(p_); } inline T* operator->() const { return p_; } @@ -66,7 +66,7 @@ class SmartPointer { // We don't have implicit conversion to a T* since that hinders migration: // You would not be able to change a method from returning a T* to - // returning an SmartPointer<T> and then get errors wherever it is used. + // returning an SmartArrayPointer<T> and then get errors wherever it is used. // If you want to take out the plain pointer and don't want it automatically @@ -78,13 +78,13 @@ class SmartPointer { return temp; } - // Assignment requires an empty (NULL) SmartPointer as the receiver. Like + // Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like // the copy constructor it removes the pointer in the original to avoid // double freeing. - inline SmartPointer& operator=(const SmartPointer<T>& rhs) { + inline SmartArrayPointer& operator=(const SmartArrayPointer<T>& rhs) { ASSERT(is_empty()); T* tmp = rhs.p_; // swap to handle self-assignment - const_cast<SmartPointer<T>&>(rhs).p_ = NULL; + const_cast<SmartArrayPointer<T>&>(rhs).p_ = NULL; p_ = tmp; return *this; } @@ -97,4 +97,4 @@ class SmartPointer { } } // namespace v8::internal -#endif // V8_SMART_POINTER_H_ +#endif // V8_SMART_ARRAY_POINTER_H_ diff --git a/deps/v8/src/spaces.h b/deps/v8/src/spaces.h index 908cd300e2..f1564967e1 100644 --- a/deps/v8/src/spaces.h +++ b/deps/v8/src/spaces.h @@ -1232,8 +1232,8 @@ class PagedSpace : public Space { // Returns the number of total pages in this space. int CountTotalPages(); #endif - private: + private: // Returns a pointer to the page of the relocation pointer. Page* MCRelocationTopPage() { return TopPageOf(mc_forwarding_info_); } @@ -1816,7 +1816,6 @@ class FixedSizeFreeList BASE_EMBEDDED { void MarkNodes(); private: - Heap* heap_; // Available bytes on the free list. diff --git a/deps/v8/src/splay-tree.h b/deps/v8/src/splay-tree.h index 0cb9ea8405..72231e4d2a 100644 --- a/deps/v8/src/splay-tree.h +++ b/deps/v8/src/splay-tree.h @@ -123,8 +123,8 @@ class SplayTree { Value value() { return value_; } Node* left() { return left_; } Node* right() { return right_; } - private: + private: friend class SplayTree; friend class Locator; Key key_; @@ -143,6 +143,7 @@ class SplayTree { Value& value() { return node_->value_; } void set_value(const Value& value) { node_->value_ = value; } inline void bind(Node* node) { node_ = node; } + private: Node* node_; }; @@ -151,7 +152,6 @@ class SplayTree { void ForEach(Callback* callback); protected: - // Resets tree root. Existing nodes become unreachable. void ResetRoot() { root_ = NULL; } @@ -187,7 +187,6 @@ class SplayTree { void Call(Node* node) { delete node; } private: - DISALLOW_COPY_AND_ASSIGN(NodeDeleter); }; diff --git a/deps/v8/src/string-stream.cc b/deps/v8/src/string-stream.cc index 9002593bdd..8086cf9515 100644 --- a/deps/v8/src/string-stream.cc +++ b/deps/v8/src/string-stream.cc @@ -252,11 +252,11 @@ void StringStream::Add(const char* format, FmtElm arg0, FmtElm arg1, } -SmartPointer<const char> StringStream::ToCString() const { +SmartArrayPointer<const char> StringStream::ToCString() const { char* str = NewArray<char>(length_ + 1); memcpy(str, buffer_, length_); str[length_] = '\0'; - return SmartPointer<const char>(str); + return SmartArrayPointer<const char>(str); } diff --git a/deps/v8/src/string-stream.h b/deps/v8/src/string-stream.h index b3f2e0d76e..0ba8f52d44 100644 --- a/deps/v8/src/string-stream.h +++ b/deps/v8/src/string-stream.h @@ -93,6 +93,7 @@ class FmtElm { FmtElm(void* value) : type_(POINTER) { // NOLINT data_.u_pointer_ = value; } + private: friend class StringStream; enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER }; @@ -142,7 +143,7 @@ class StringStream { void OutputToStdOut() { OutputToFile(stdout); } void Log(); Handle<String> ToString(); - SmartPointer<const char> ToCString() const; + SmartArrayPointer<const char> ToCString() const; int length() const { return length_; } // Object printing support. diff --git a/deps/v8/src/string.js b/deps/v8/src/string.js index 6f68ce0890..297105d047 100644 --- a/deps/v8/src/string.js +++ b/deps/v8/src/string.js @@ -223,7 +223,7 @@ function StringReplace(search, replace) { // Delegate to one of the regular expression variants if necessary. if (IS_REGEXP(search)) { %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]); - if (IS_FUNCTION(replace)) { + if (IS_SPEC_FUNCTION(replace)) { if (search.global) { return StringReplaceGlobalRegExpWithFunction(subject, search, replace); } else { @@ -250,7 +250,7 @@ function StringReplace(search, replace) { builder.addSpecialSlice(0, start); // Compute the string to replace with. - if (IS_FUNCTION(replace)) { + if (IS_SPEC_FUNCTION(replace)) { var receiver = %GetDefaultReceiver(replace); builder.add(%_CallFunction(receiver, search, @@ -440,13 +440,14 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) { i++; } } else { + var receiver = %GetDefaultReceiver(replace); while (i < len) { var elem = res[i]; if (!%_IsSmi(elem)) { // elem must be an Array. // Use the apply argument as backing for global RegExp properties. lastMatchInfoOverride = elem; - var func_result = replace.apply(null, elem); + var func_result = %Apply(replace, receiver, elem, 0, elem.length); res[i] = TO_STRING_INLINE(func_result); } i++; @@ -472,11 +473,11 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { // The number of captures plus one for the match. var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; var replacement; + var receiver = %GetDefaultReceiver(replace); if (m == 1) { // No captures, only the match, which is always valid. var s = SubString(subject, index, endOfMatch); // Don't call directly to avoid exposing the built-in global object. - var receiver = %GetDefaultReceiver(replace); replacement = %_CallFunction(receiver, s, index, subject, replace); } else { @@ -487,7 +488,7 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { parameters[j] = index; parameters[j + 1] = subject; - replacement = replace.apply(null, parameters); + replacement = %Apply(replace, receiver, parameters, 0, j + 2); } result.add(replacement); // The add method converts to string if necessary. diff --git a/deps/v8/src/stub-cache.cc b/deps/v8/src/stub-cache.cc index 13b0b633b1..55963303c4 100644 --- a/deps/v8/src/stub-cache.cc +++ b/deps/v8/src/stub-cache.cc @@ -74,7 +74,7 @@ Code* StubCache::Set(String* name, Map* map, Code* code) { // the bits are the least significant so they will be the ones // masked out. ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC); - ASSERT(Code::kFlagsICStateShift == 0); + STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1); // Make sure that the code type is not included in the hash. ASSERT(Code::ExtractTypeFromFlags(flags) == 0); @@ -652,7 +652,6 @@ MaybeObject* StubCache::ComputeKeyedStoreField(String* name, (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) MaybeObject* StubCache::ComputeCallConstant(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state, String* name, @@ -678,7 +677,6 @@ MaybeObject* StubCache::ComputeCallConstant(int argc, CONSTANT_FUNCTION, extra_ic_state, cache_holder, - in_loop, argc); Object* code = map_holder->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { @@ -688,8 +686,7 @@ MaybeObject* StubCache::ComputeCallConstant(int argc, // caches. if (!function->is_compiled()) return Failure::InternalError(); // Compile the stub - only create stubs for fully compiled functions. - CallStubCompiler compiler( - argc, in_loop, kind, extra_ic_state, cache_holder); + CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); { MaybeObject* maybe_code = compiler.CompileCallConstant(object, holder, function, name, check); if (!maybe_code->ToObject(&code)) return maybe_code; @@ -711,7 +708,6 @@ MaybeObject* StubCache::ComputeCallConstant(int argc, MaybeObject* StubCache::ComputeCallField(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state, String* name, @@ -734,12 +730,10 @@ MaybeObject* StubCache::ComputeCallField(int argc, FIELD, extra_ic_state, cache_holder, - in_loop, argc); Object* code = map_holder->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { - CallStubCompiler compiler( - argc, in_loop, kind, extra_ic_state, cache_holder); + CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); { MaybeObject* maybe_code = compiler.CompileCallField(JSObject::cast(object), holder, @@ -785,12 +779,10 @@ MaybeObject* StubCache::ComputeCallInterceptor( INTERCEPTOR, extra_ic_state, cache_holder, - NOT_IN_LOOP, argc); Object* code = map_holder->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { - CallStubCompiler compiler( - argc, NOT_IN_LOOP, kind, extra_ic_state, cache_holder); + CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); { MaybeObject* maybe_code = compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); if (!maybe_code->ToObject(&code)) return maybe_code; @@ -811,14 +803,12 @@ MaybeObject* StubCache::ComputeCallInterceptor( MaybeObject* StubCache::ComputeCallNormal(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state, String* name, JSObject* receiver) { Object* code; - { MaybeObject* maybe_code = - ComputeCallNormal(argc, in_loop, kind, extra_ic_state); + { MaybeObject* maybe_code = ComputeCallNormal(argc, kind, extra_ic_state); if (!maybe_code->ToObject(&code)) return maybe_code; } return code; @@ -826,7 +816,6 @@ MaybeObject* StubCache::ComputeCallNormal(int argc, MaybeObject* StubCache::ComputeCallGlobal(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state, String* name, @@ -841,7 +830,6 @@ MaybeObject* StubCache::ComputeCallGlobal(int argc, NORMAL, extra_ic_state, cache_holder, - in_loop, argc); Object* code = map_holder->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { @@ -850,8 +838,7 @@ MaybeObject* StubCache::ComputeCallGlobal(int argc, // internal error which will make sure we do not update any // caches. if (!function->is_compiled()) return Failure::InternalError(); - CallStubCompiler compiler( - argc, in_loop, kind, extra_ic_state, cache_holder); + CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder); { MaybeObject* maybe_code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); if (!maybe_code->ToObject(&code)) return maybe_code; @@ -920,14 +907,12 @@ static MaybeObject* FillCache(Isolate* isolate, MaybeObject* maybe_code) { Code* StubCache::FindCallInitialize(int argc, - InLoopFlag in_loop, RelocInfo::Mode mode, Code::Kind kind) { Code::ExtraICState extra_state = CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); Code::Flags flags = Code::ComputeFlags(kind, - in_loop, UNINITIALIZED, extra_state, NORMAL, @@ -941,14 +926,12 @@ Code* StubCache::FindCallInitialize(int argc, MaybeObject* StubCache::ComputeCallInitialize(int argc, - InLoopFlag in_loop, RelocInfo::Mode mode, Code::Kind kind) { Code::ExtraICState extra_state = CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); Code::Flags flags = Code::ComputeFlags(kind, - in_loop, UNINITIALIZED, extra_state, NORMAL, @@ -964,49 +947,26 @@ MaybeObject* StubCache::ComputeCallInitialize(int argc, Handle<Code> StubCache::ComputeCallInitialize(int argc, - InLoopFlag in_loop, RelocInfo::Mode mode) { - if (in_loop == IN_LOOP) { - // Force the creation of the corresponding stub outside loops, - // because it may be used when clearing the ICs later - it is - // possible for a series of IC transitions to lose the in-loop - // information, and the IC clearing code can't generate a stub - // that it needs so we need to ensure it is generated already. - ComputeCallInitialize(argc, NOT_IN_LOOP, mode); - } CALL_HEAP_FUNCTION(isolate_, - ComputeCallInitialize(argc, in_loop, mode, Code::CALL_IC), + ComputeCallInitialize(argc, mode, Code::CALL_IC), Code); } -Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc, - InLoopFlag in_loop) { - if (in_loop == IN_LOOP) { - // Force the creation of the corresponding stub outside loops, - // because it may be used when clearing the ICs later - it is - // possible for a series of IC transitions to lose the in-loop - // information, and the IC clearing code can't generate a stub - // that it needs so we need to ensure it is generated already. - ComputeKeyedCallInitialize(argc, NOT_IN_LOOP); - } +Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { CALL_HEAP_FUNCTION( isolate_, - ComputeCallInitialize(argc, - in_loop, - RelocInfo::CODE_TARGET, - Code::KEYED_CALL_IC), + ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, Code::KEYED_CALL_IC), Code); } MaybeObject* StubCache::ComputeCallPreMonomorphic( int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state) { Code::Flags flags = Code::ComputeFlags(kind, - in_loop, PREMONOMORPHIC, extra_ic_state, NORMAL, @@ -1022,11 +982,9 @@ MaybeObject* StubCache::ComputeCallPreMonomorphic( MaybeObject* StubCache::ComputeCallNormal(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state) { Code::Flags flags = Code::ComputeFlags(kind, - in_loop, MONOMORPHIC, extra_ic_state, NORMAL, @@ -1041,12 +999,9 @@ MaybeObject* StubCache::ComputeCallNormal(int argc, } -MaybeObject* StubCache::ComputeCallArguments(int argc, - InLoopFlag in_loop, - Code::Kind kind) { +MaybeObject* StubCache::ComputeCallArguments(int argc, Code::Kind kind) { ASSERT(kind == Code::KEYED_CALL_IC); Code::Flags flags = Code::ComputeFlags(kind, - in_loop, MEGAMORPHIC, Code::kNoExtraICState, NORMAL, @@ -1063,11 +1018,9 @@ MaybeObject* StubCache::ComputeCallArguments(int argc, MaybeObject* StubCache::ComputeCallMegamorphic( int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state) { Code::Flags flags = Code::ComputeFlags(kind, - in_loop, MEGAMORPHIC, extra_ic_state, NORMAL, @@ -1088,7 +1041,6 @@ MaybeObject* StubCache::ComputeCallMiss(int argc, // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs // and monomorphic stubs are not mixed up together in the stub cache. Code::Flags flags = Code::ComputeFlags(kind, - NOT_IN_LOOP, MONOMORPHIC_PROTOTYPE_FAILURE, extra_ic_state, NORMAL, @@ -1111,7 +1063,6 @@ MaybeObject* StubCache::ComputeCallDebugBreak( // Extra IC state is irrelevant for debug break ICs. They jump to // the actual call ic to carry out the work. Code::Flags flags = Code::ComputeFlags(kind, - NOT_IN_LOOP, DEBUG_BREAK, Code::kNoExtraICState, NORMAL, @@ -1132,7 +1083,6 @@ MaybeObject* StubCache::ComputeCallDebugPrepareStepIn( // Extra IC state is irrelevant for debug break ICs. They jump to // the actual call ic to carry out the work. Code::Flags flags = Code::ComputeFlags(kind, - NOT_IN_LOOP, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState, NORMAL, @@ -1672,7 +1622,7 @@ MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type, String* name, InlineCacheState state) { Code::Flags flags = Code::ComputeFlags( - Code::KEYED_LOAD_IC, NOT_IN_LOOP, state, Code::kNoExtraICState, type); + Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); MaybeObject* result = GetCodeWithFlags(flags, name); if (!result->IsFailure()) { PROFILE(isolate(), @@ -1688,8 +1638,8 @@ MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type, MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) { - Code::Flags flags = Code::ComputeMonomorphicFlags( - Code::STORE_IC, type, strict_mode_); + Code::Flags flags = + Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); MaybeObject* result = GetCodeWithFlags(flags, name); if (!result->IsFailure()) { PROFILE(isolate(), @@ -1707,8 +1657,8 @@ MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) { MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name, InlineCacheState state) { - Code::Flags flags = Code::ComputeFlags( - Code::KEYED_STORE_IC, NOT_IN_LOOP, state, strict_mode_, type); + Code::Flags flags = + Code::ComputeFlags(Code::KEYED_STORE_IC, state, strict_mode_, type); MaybeObject* result = GetCodeWithFlags(flags, name); if (!result->IsFailure()) { PROFILE(isolate(), @@ -1730,12 +1680,10 @@ void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( CallStubCompiler::CallStubCompiler(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state, InlineCacheHolderFlag cache_holder) : arguments_(argc), - in_loop_(in_loop), kind_(kind), extra_ic_state_(extra_ic_state), cache_holder_(cache_holder) { @@ -1796,7 +1744,6 @@ MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) { type, extra_ic_state_, cache_holder_, - in_loop_, argc); return GetCodeWithFlags(flags, name); } diff --git a/deps/v8/src/stub-cache.h b/deps/v8/src/stub-cache.h index dd06a1c078..18c157b165 100644 --- a/deps/v8/src/stub-cache.h +++ b/deps/v8/src/stub-cache.h @@ -194,7 +194,6 @@ class StubCache { MUST_USE_RESULT MaybeObject* ComputeCallField( int argc, - InLoopFlag in_loop, Code::Kind, Code::ExtraICState extra_ic_state, String* name, @@ -204,7 +203,6 @@ class StubCache { MUST_USE_RESULT MaybeObject* ComputeCallConstant( int argc, - InLoopFlag in_loop, Code::Kind, Code::ExtraICState extra_ic_state, String* name, @@ -214,7 +212,6 @@ class StubCache { MUST_USE_RESULT MaybeObject* ComputeCallNormal( int argc, - InLoopFlag in_loop, Code::Kind, Code::ExtraICState extra_ic_state, String* name, @@ -230,7 +227,6 @@ class StubCache { MUST_USE_RESULT MaybeObject* ComputeCallGlobal( int argc, - InLoopFlag in_loop, Code::Kind, Code::ExtraICState extra_ic_state, String* name, @@ -242,33 +238,27 @@ class StubCache { // --- MUST_USE_RESULT MaybeObject* ComputeCallInitialize(int argc, - InLoopFlag in_loop, RelocInfo::Mode mode, Code::Kind kind); Handle<Code> ComputeCallInitialize(int argc, - InLoopFlag in_loop, RelocInfo::Mode mode); - Handle<Code> ComputeKeyedCallInitialize(int argc, InLoopFlag in_loop); + Handle<Code> ComputeKeyedCallInitialize(int argc); MUST_USE_RESULT MaybeObject* ComputeCallPreMonomorphic( int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state); MUST_USE_RESULT MaybeObject* ComputeCallNormal(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState state); MUST_USE_RESULT MaybeObject* ComputeCallArguments(int argc, - InLoopFlag in_loop, Code::Kind kind); MUST_USE_RESULT MaybeObject* ComputeCallMegamorphic(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState state); @@ -278,7 +268,6 @@ class StubCache { // Finds the Code object stored in the Heap::non_monomorphic_cache(). MUST_USE_RESULT Code* FindCallInitialize(int argc, - InLoopFlag in_loop, RelocInfo::Mode mode, Code::Kind kind); @@ -379,11 +368,7 @@ class StubCache { // Use the seed from the primary cache in the secondary cache. uint32_t string_low32bits = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)); - // We always set the in_loop bit to zero when generating the lookup code - // so do it here too so the hash codes match. - uint32_t iflags = - (static_cast<uint32_t>(flags) & ~Code::kFlagsICInLoopMask); - uint32_t key = seed - string_low32bits + iflags; + uint32_t key = seed - string_low32bits + flags; return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize); } @@ -660,7 +645,7 @@ class KeyedLoadStubCompiler: public StubCompiler { CodeList* handler_ics); static void GenerateLoadExternalArray(MacroAssembler* masm, - JSObject::ElementsKind elements_kind); + ElementsKind elements_kind); static void GenerateLoadFastElement(MacroAssembler* masm); @@ -725,7 +710,7 @@ class KeyedStoreStubCompiler: public StubCompiler { bool is_js_array); static void GenerateStoreExternalArray(MacroAssembler* masm, - JSObject::ElementsKind elements_kind); + ElementsKind elements_kind); static void GenerateStoreDictionaryElement(MacroAssembler* masm); @@ -755,7 +740,6 @@ class CallOptimization; class CallStubCompiler: public StubCompiler { public: CallStubCompiler(int argc, - InLoopFlag in_loop, Code::Kind kind, Code::ExtraICState extra_ic_state, InlineCacheHolderFlag cache_holder); @@ -815,7 +799,6 @@ class CallStubCompiler: public StubCompiler { String* name); const ParameterCount arguments_; - const InLoopFlag in_loop_; const Code::Kind kind_; const Code::ExtraICState extra_ic_state_; const InlineCacheHolderFlag cache_holder_; diff --git a/deps/v8/src/type-info.cc b/deps/v8/src/type-info.cc index bdf7bc3c86..c64368e599 100644 --- a/deps/v8/src/type-info.cc +++ b/deps/v8/src/type-info.cc @@ -190,7 +190,6 @@ void TypeFeedbackOracle::CallReceiverTypes(Call* expr, NORMAL, extra_ic_state, OWN_MAP, - NOT_IN_LOOP, arity); CollectReceiverTypes(expr->id(), name, flags, types); } diff --git a/deps/v8/src/utils.h b/deps/v8/src/utils.h index 5a875d8271..26c522b89f 100644 --- a/deps/v8/src/utils.h +++ b/deps/v8/src/utils.h @@ -203,16 +203,17 @@ inline int StrLength(const char* string) { template<class T, int shift, int size> class BitField { public: + // A uint32_t mask of bit field. To use all bits of a uint32 in a + // bitfield without compiler warnings we have to compute 2^32 without + // using a shift count of 32. + static const uint32_t kMask = ((1U << shift) << size) - (1U << shift); + + // Value for the field with all bits set. + static const T kMax = static_cast<T>((1U << size) - 1); + // Tells whether the provided value fits into the bit field. static bool is_valid(T value) { - return (static_cast<uint32_t>(value) & ~((1U << (size)) - 1)) == 0; - } - - // Returns a uint32_t mask of bit field. - static uint32_t mask() { - // To use all bits of a uint32 in a bitfield without compiler warnings we - // have to compute 2^32 without using a shift count of 32. - return ((1U << shift) << size) - (1U << shift); + return (static_cast<uint32_t>(value) & ~static_cast<uint32_t>(kMax)) == 0; } // Returns a uint32_t with the bit field value encoded. @@ -223,17 +224,12 @@ class BitField { // Returns a uint32_t with the bit field value updated. static uint32_t update(uint32_t previous, T value) { - return (previous & ~mask()) | encode(value); + return (previous & ~kMask) | encode(value); } // Extracts the bit field from the value. static T decode(uint32_t value) { - return static_cast<T>((value & mask()) >> shift); - } - - // Value for the field with all bits set. - static T max() { - return decode(mask()); + return static_cast<T>((value & kMask) >> shift); } }; @@ -890,6 +886,7 @@ class SimpleStringBuilder { int position_; bool is_finalized() const { return position_ < 0; } + private: DISALLOW_IMPLICIT_CONSTRUCTORS(SimpleStringBuilder); }; diff --git a/deps/v8/src/v8globals.h b/deps/v8/src/v8globals.h index aff27579f8..eb5c49d751 100644 --- a/deps/v8/src/v8globals.h +++ b/deps/v8/src/v8globals.h @@ -302,12 +302,6 @@ enum CheckType { }; -enum InLoopFlag { - NOT_IN_LOOP, - IN_LOOP -}; - - enum CallFunctionFlags { NO_CALL_FUNCTION_FLAGS = 0, // Receiver might implicitly be the global objects. If it is, the @@ -334,7 +328,7 @@ enum PropertyType { HANDLER = 4, // only in lookup results, not in descriptors INTERCEPTOR = 5, // only in lookup results, not in descriptors MAP_TRANSITION = 6, // only in fast mode - EXTERNAL_ARRAY_TRANSITION = 7, + ELEMENTS_TRANSITION = 7, CONSTANT_TRANSITION = 8, // only in fast mode NULL_DESCRIPTOR = 9, // only in fast mode // All properties before MAP_TRANSITION are real. diff --git a/deps/v8/src/v8natives.js b/deps/v8/src/v8natives.js index 1616ac366b..588bdb21bb 100644 --- a/deps/v8/src/v8natives.js +++ b/deps/v8/src/v8natives.js @@ -298,7 +298,7 @@ function ObjectDefineGetter(name, fun) { if (receiver == null && !IS_UNDETECTABLE(receiver)) { receiver = %GlobalReceiver(global); } - if (!IS_FUNCTION(fun)) { + if (!IS_SPEC_FUNCTION(fun)) { throw new $TypeError('Object.prototype.__defineGetter__: Expecting function'); } var desc = new PropertyDescriptor(); @@ -323,7 +323,7 @@ function ObjectDefineSetter(name, fun) { if (receiver == null && !IS_UNDETECTABLE(receiver)) { receiver = %GlobalReceiver(global); } - if (!IS_FUNCTION(fun)) { + if (!IS_SPEC_FUNCTION(fun)) { throw new $TypeError( 'Object.prototype.__defineSetter__: Expecting function'); } @@ -453,7 +453,7 @@ function ToPropertyDescriptor(obj) { if ("get" in obj) { var get = obj.get; - if (!IS_UNDEFINED(get) && !IS_FUNCTION(get)) { + if (!IS_UNDEFINED(get) && !IS_SPEC_FUNCTION(get)) { throw MakeTypeError("getter_must_be_callable", [get]); } desc.setGet(get); @@ -461,7 +461,7 @@ function ToPropertyDescriptor(obj) { if ("set" in obj) { var set = obj.set; - if (!IS_UNDEFINED(set) && !IS_FUNCTION(set)) { + if (!IS_UNDEFINED(set) && !IS_SPEC_FUNCTION(set)) { throw MakeTypeError("setter_must_be_callable", [set]); } desc.setSet(set); @@ -623,7 +623,7 @@ function GetTrap(handler, name, defaultTrap) { throw MakeTypeError("handler_trap_missing", [handler, name]); } trap = defaultTrap; - } else if (!IS_FUNCTION(trap)) { + } else if (!IS_SPEC_FUNCTION(trap)) { throw MakeTypeError("handler_trap_must_be_callable", [handler, name]); } return trap; @@ -977,7 +977,7 @@ function ObjectDefineProperty(obj, p, attributes) { // Clone the attributes object for protection. // TODO(rossberg): not spec'ed yet, so not sure if this should involve // non-own properties as it does (or non-enumerable ones, as it doesn't?). - var attributesClone = {} + var attributesClone = {}; for (var a in attributes) { attributesClone[a] = attributes[a]; } @@ -1041,7 +1041,16 @@ function ProxyFix(obj) { if (IS_UNDEFINED(props)) { throw MakeTypeError("handler_returned_undefined", [handler, "fix"]); } - %Fix(obj); + + if (IS_SPEC_FUNCTION(obj)) { + var callTrap = %GetCallTrap(obj); + var constructTrap = %GetConstructTrap(obj); + var code = DelegateCallAndConstruct(callTrap, constructTrap); + %Fix(obj); // becomes a regular function + %SetCode(obj, code); + } else { + %Fix(obj); + } ObjectDefineProperties(obj, props); } @@ -1412,6 +1421,10 @@ SetUpNumber(); $Function.prototype.constructor = $Function; function FunctionSourceString(func) { + while (%IsJSFunctionProxy(func)) { + func = %GetCallTrap(func); + } + if (!IS_FUNCTION(func)) { throw new $TypeError('Function.prototype.toString is not generic'); } @@ -1441,12 +1454,13 @@ function FunctionToString() { // ES5 15.3.4.5 function FunctionBind(this_arg) { // Length is 1. - if (!IS_FUNCTION(this)) { + if (!IS_SPEC_FUNCTION(this)) { 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) - 1; var fn = this; + if (argc_bound == 0) { var result = function() { if (%_IsConstructCall()) { @@ -1455,8 +1469,7 @@ function FunctionBind(this_arg) { // Length is 1. // materializing it and guarantee that this function will be optimized. return %NewObjectFromBound(fn, null); } - - return fn.apply(this_arg, arguments); + return %Apply(fn, this_arg, arguments, 0, %_ArgumentsLength()); }; } else { var bound_args = new InternalArray(argc_bound); @@ -1486,7 +1499,7 @@ function FunctionBind(this_arg) { // Length is 1. for (var i = 0; i < argc; i++) { args[argc_bound + i] = %_Arguments(i); } - return fn.apply(this_arg, args); + return %Apply(fn, this_arg, args, 0, argc + argc_bound); }; } @@ -1497,11 +1510,16 @@ function FunctionBind(this_arg) { // Length is 1. // is called and make them non-enumerable and non-configurable. // To be consistent with our normal functions we leave this as it is. - // Set the correct length. - var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; %FunctionRemovePrototype(result); %FunctionSetBound(result); - %BoundFunctionSetLength(result, length); + // Set the correct length. If this is a function proxy, this.length might + // throw, or return a bogus result. Leave length alone in that case. + // TODO(rossberg): This is underspecified in the current proxy proposal. + try { + var old_length = ToInteger(this.length); + var length = (old_length - argc_bound) > 0 ? old_length - argc_bound : 0; + %BoundFunctionSetLength(result, length); + } catch(x) {} return result; } diff --git a/deps/v8/src/v8threads.h b/deps/v8/src/v8threads.h index 3ba823a720..4002bb36c0 100644 --- a/deps/v8/src/v8threads.h +++ b/deps/v8/src/v8threads.h @@ -54,6 +54,7 @@ class ThreadState { // Get data area for archiving a thread. char* data() { return data_; } + private: explicit ThreadState(ThreadManager* thread_manager); diff --git a/deps/v8/src/variables.cc b/deps/v8/src/variables.cc index 6cf6e0b04a..971061b053 100644 --- a/deps/v8/src/variables.cc +++ b/deps/v8/src/variables.cc @@ -66,7 +66,7 @@ Variable::Variable(Scope* scope, index_(-1), local_if_not_shadowed_(NULL), is_valid_LHS_(is_valid_LHS), - is_accessed_from_inner_function_scope_(false), + is_accessed_from_inner_scope_(false), is_used_(false) { // names must be canonicalized for fast equality checks ASSERT(name->IsSymbol()); diff --git a/deps/v8/src/variables.h b/deps/v8/src/variables.h index a4ead51b89..56c8dabd37 100644 --- a/deps/v8/src/variables.h +++ b/deps/v8/src/variables.h @@ -120,12 +120,12 @@ class Variable: public ZoneObject { Handle<String> name() const { return name_; } Mode mode() const { return mode_; } - bool is_accessed_from_inner_function_scope() const { - return is_accessed_from_inner_function_scope_; + bool is_accessed_from_inner_scope() const { + return is_accessed_from_inner_scope_; } - void MarkAsAccessedFromInnerFunctionScope() { + void MarkAsAccessedFromInnerScope() { ASSERT(mode_ != TEMPORARY); - is_accessed_from_inner_function_scope_ = true; + is_accessed_from_inner_scope_ = true; } bool is_used() { return is_used_; } void set_is_used(bool flag) { is_used_ = flag; } @@ -188,7 +188,7 @@ class Variable: public ZoneObject { bool is_valid_LHS_; // Usage info. - bool is_accessed_from_inner_function_scope_; // set by variable resolver + bool is_accessed_from_inner_scope_; // set by variable resolver bool is_used_; }; diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc index 53b1758c50..e16b63eb8e 100644 --- a/deps/v8/src/version.cc +++ b/deps/v8/src/version.cc @@ -34,7 +34,7 @@ // cannot be changed without changing the SCons build script. #define MAJOR_VERSION 3 #define MINOR_VERSION 6 -#define BUILD_NUMBER 2 +#define BUILD_NUMBER 4 #define PATCH_LEVEL 0 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/weakmap.js b/deps/v8/src/weakmap.js index 6c15e30fb6..5fb5151071 100644 --- a/deps/v8/src/weakmap.js +++ b/deps/v8/src/weakmap.js @@ -85,9 +85,6 @@ function WeakMapDelete(key) { // Set up the WeakMap constructor function. %SetCode($WeakMap, WeakMapConstructor); - // Set up the WeakMap prototype object. - %FunctionSetPrototype($WeakMap, new $WeakMap()); - // Set up the constructor property on the WeakMap prototype object. %SetProperty($WeakMap.prototype, "constructor", $WeakMap, DONT_ENUM); diff --git a/deps/v8/src/x64/assembler-x64.h b/deps/v8/src/x64/assembler-x64.h index c23eb16897..2e373faac5 100644 --- a/deps/v8/src/x64/assembler-x64.h +++ b/deps/v8/src/x64/assembler-x64.h @@ -453,6 +453,7 @@ class CpuFeatures : public AllStatic { // Enable a specified feature within a scope. class Scope BASE_EMBEDDED { #ifdef DEBUG + public: explicit Scope(CpuFeature f) { uint64_t mask = V8_UINT64_C(1) << f; @@ -472,10 +473,12 @@ class CpuFeatures : public AllStatic { isolate_->set_enabled_cpu_features(old_enabled_); } } + private: Isolate* isolate_; uint64_t old_enabled_; #else + public: explicit Scope(CpuFeature f) {} #endif diff --git a/deps/v8/src/x64/builtins-x64.cc b/deps/v8/src/x64/builtins-x64.cc index 7c6f7e327c..db06909daa 100644 --- a/deps/v8/src/x64/builtins-x64.cc +++ b/deps/v8/src/x64/builtins-x64.cc @@ -655,15 +655,16 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { // 2. Get the function to call (passed as receiver) from the stack, check // if it is a function. - Label non_function; + Label slow, non_function; // The function to call is at position n+1 on the stack. __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); __ JumpIfSmi(rdi, &non_function); __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); - __ j(not_equal, &non_function); + __ j(not_equal, &slow); // 3a. Patch the first argument if necessary when calling a function. Label shift_arguments; + __ Set(rdx, 0); // indicate regular JS_FUNCTION { Label convert_to_object, use_global_receiver, patch_receiver; // Change context eagerly in case we need the global receiver. __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); @@ -701,6 +702,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ push(rbx); __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); __ movq(rbx, rax); + __ Set(rdx, 0); // indicate regular JS_FUNCTION __ pop(rax); __ SmiToInteger32(rax, rax); @@ -725,14 +727,19 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ jmp(&shift_arguments); } + // 3b. Check for function proxy. + __ bind(&slow); + __ Set(rdx, 1); // indicate function proxy + __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); + __ j(equal, &shift_arguments); + __ bind(&non_function); + __ Set(rdx, 2); // indicate non-function - // 3b. Patch the first argument when calling a non-function. The + // 3c. Patch the first argument when calling a non-function. The // CALL_NON_FUNCTION builtin expects the non-function callee as // receiver, so overwrite the first argument which will ultimately // become the receiver. - __ bind(&non_function); __ movq(Operand(rsp, rax, times_pointer_size, 0), rdi); - __ Set(rdi, 0); // 4. Shift arguments and return address one slot down on the stack // (overwriting the original receiver). Adjust argument count to make @@ -749,13 +756,26 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ decq(rax); // One fewer argument (first argument is new receiver). } - // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. - { Label function; - __ testq(rdi, rdi); - __ j(not_zero, &function); + // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, + // or a function proxy via CALL_FUNCTION_PROXY. + { Label function, non_proxy; + __ testq(rdx, rdx); + __ j(zero, &function); __ Set(rbx, 0); - __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); __ SetCallKind(rcx, CALL_AS_METHOD); + __ cmpq(rdx, Immediate(1)); + __ j(not_equal, &non_proxy); + + __ pop(rdx); // return address + __ push(rdi); // re-add proxy object as additional argument + __ push(rdx); + __ incq(rax); + __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); + __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), + RelocInfo::CODE_TARGET); + + __ bind(&non_proxy); + __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), RelocInfo::CODE_TARGET); __ bind(&function); @@ -797,11 +817,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { static const int kArgumentsOffset = 2 * kPointerSize; static const int kReceiverOffset = 3 * kPointerSize; static const int kFunctionOffset = 4 * kPointerSize; + __ push(Operand(rbp, kFunctionOffset)); __ push(Operand(rbp, kArgumentsOffset)); __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); - // Check the stack for overflow. We are not trying need to catch + // Check the stack for overflow. We are not trying to catch // interruptions (e.g. debug break and preemption) here, so the "real stack // limit" is checked. Label okay; @@ -831,16 +852,20 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ push(rax); // limit __ push(Immediate(0)); // index - // Change context eagerly to get the right global object if - // necessary. + // Get the receiver. + __ movq(rbx, Operand(rbp, kReceiverOffset)); + + // Check that the function is a JS function (otherwise it must be a proxy). + Label push_receiver; __ movq(rdi, Operand(rbp, kFunctionOffset)); - __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); + __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); + __ j(not_equal, &push_receiver); - // Compute the receiver. - Label call_to_object, use_global_receiver, push_receiver; - __ movq(rbx, Operand(rbp, kReceiverOffset)); + // Change context eagerly to get the right global object if necessary. + __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); // Do not transform the receiver for strict mode functions. + Label call_to_object, use_global_receiver; __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); __ testb(FieldOperand(rdx, SharedFunctionInfo::kStrictModeByteOffset), Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); @@ -913,14 +938,30 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ j(not_equal, &loop); // Invoke the function. + Label call_proxy; ParameterCount actual(rax); __ SmiToInteger32(rax, rax); __ movq(rdi, Operand(rbp, kFunctionOffset)); + __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); + __ j(not_equal, &call_proxy); __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); __ LeaveInternalFrame(); - __ ret(3 * kPointerSize); // remove function, receiver, and arguments + __ ret(3 * kPointerSize); // remove this, receiver, and arguments + + // Invoke the function proxy. + __ bind(&call_proxy); + __ push(rdi); // add function proxy as last argument + __ incq(rax); + __ Set(rbx, 0); + __ SetCallKind(rcx, CALL_AS_METHOD); + __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); + __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), + RelocInfo::CODE_TARGET); + + __ LeaveInternalFrame(); + __ ret(3 * kPointerSize); // remove this, receiver, and arguments } diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc index 2ae4d9f7ab..df4438b734 100644 --- a/deps/v8/src/x64/code-stubs-x64.cc +++ b/deps/v8/src/x64/code-stubs-x64.cc @@ -2712,7 +2712,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { // haven't created the exception yet. Handle that in the runtime system. // TODO(592): Rerunning the RegExp to get the stack overflow exception. ExternalReference pending_exception_address( - Isolate::k_pending_exception_address, isolate); + Isolate::kPendingExceptionAddress, isolate); Operand pending_exception_operand = masm->ExternalOperand(pending_exception_address, rbx); __ movq(rax, pending_exception_operand); @@ -3232,7 +3232,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) { void CallFunctionStub::Generate(MacroAssembler* masm) { - Label slow; + Label slow, non_function; // The receiver might implicitly be the global object. This is // indicated by passing the hole as the receiver to the call @@ -3257,7 +3257,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize)); // Check that the function really is a JavaScript function. - __ JumpIfSmi(rdi, &slow); + __ JumpIfSmi(rdi, &non_function); // Goto slow case if we do not have a function. __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); __ j(not_equal, &slow); @@ -3284,15 +3284,32 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); + // Check for function proxy. + __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); + __ j(not_equal, &non_function); + __ pop(rcx); + __ push(rdi); // put proxy as additional argument under return address + __ push(rcx); + __ Set(rax, argc_ + 1); + __ Set(rbx, 0); + __ SetCallKind(rcx, CALL_AS_FUNCTION); + __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); + { + Handle<Code> adaptor = + masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); + __ jmp(adaptor, RelocInfo::CODE_TARGET); + } + // CALL_NON_FUNCTION expects the non-function callee as receiver (instead // of the original receiver from the call site). + __ bind(&non_function); __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi); __ Set(rax, argc_); __ Set(rbx, 0); + __ SetCallKind(rcx, CALL_AS_METHOD); __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); Handle<Code> adaptor = Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline(); - __ SetCallKind(rcx, CALL_AS_METHOD); __ Jump(adaptor, RelocInfo::CODE_TARGET); } @@ -3428,7 +3445,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, // Retrieve the pending exception and clear the variable. ExternalReference pending_exception_address( - Isolate::k_pending_exception_address, masm->isolate()); + Isolate::kPendingExceptionAddress, masm->isolate()); Operand pending_exception_operand = masm->ExternalOperand(pending_exception_address); __ movq(rax, pending_exception_operand); @@ -3568,14 +3585,14 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { Isolate* isolate = masm->isolate(); // Save copies of the top frame descriptor on the stack. - ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, isolate); + ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, isolate); { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp); __ push(c_entry_fp_operand); } // If this is the outermost JS call, set js_entry_sp value. - ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); + ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate); __ Load(rax, js_entry_sp); __ testq(rax, rax); __ j(not_zero, ¬_outermost_js); @@ -3593,7 +3610,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Caught exception: Store result (exception) in the pending // exception field in the JSEnv and return a failure sentinel. - ExternalReference pending_exception(Isolate::k_pending_exception_address, + ExternalReference pending_exception(Isolate::kPendingExceptionAddress, isolate); __ Store(pending_exception, rax); __ movq(rax, Failure::Exception(), RelocInfo::NONE); diff --git a/deps/v8/src/x64/full-codegen-x64.cc b/deps/v8/src/x64/full-codegen-x64.cc index ba8e0f627e..bd3e769021 100644 --- a/deps/v8/src/x64/full-codegen-x64.cc +++ b/deps/v8/src/x64/full-codegen-x64.cc @@ -1926,9 +1926,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr, // Record source position for debugger. SetSourcePosition(expr->position()); // Call the IC initialization code. - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic = - ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ call(ic, mode, expr->id()); RecordJSReturnSite(expr); // Restore context register. @@ -1959,9 +1958,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, // Record source position for debugger. SetSourcePosition(expr->position()); // Call the IC initialization code. - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic = - ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); + isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. __ call(ic, RelocInfo::CODE_TARGET, expr->id()); RecordJSReturnSite(expr); @@ -1982,8 +1980,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, flags); + CallFunctionStub stub(arg_count, flags); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -2075,8 +2072,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { } // Record source position for debugger. SetSourcePosition(expr->position()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; - CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT); + CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); __ CallStub(&stub); RecordJSReturnSite(expr); // Restore context register. @@ -3477,10 +3473,9 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { if (expr->is_jsruntime()) { // Call the JS runtime function using a call IC. __ Move(rcx, expr->name()); - InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; RelocInfo::Mode mode = RelocInfo::CODE_TARGET; Handle<Code> ic = - ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); + isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); __ call(ic, mode, expr->id()); // Restore context register. __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); diff --git a/deps/v8/src/x64/ic-x64.cc b/deps/v8/src/x64/ic-x64.cc index 990c171bed..9d55594dcb 100644 --- a/deps/v8/src/x64/ic-x64.cc +++ b/deps/v8/src/x64/ic-x64.cc @@ -145,7 +145,7 @@ static void GenerateDictionaryLoad(MacroAssembler* masm, const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; __ Test(Operand(elements, r1, times_pointer_size, kDetailsOffset - kHeapObjectTag), - Smi::FromInt(PropertyDetails::TypeField::mask())); + Smi::FromInt(PropertyDetails::TypeField::kMask)); __ j(not_zero, miss_label); // Get the value at the masked, scaled index. @@ -201,9 +201,9 @@ static void GenerateDictionaryStore(MacroAssembler* masm, StringDictionary::kHeaderSize + StringDictionary::kElementsStartIndex * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask - = (PropertyDetails::TypeField::mask() | - PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; + const int kTypeAndReadOnlyMask = + (PropertyDetails::TypeField::kMask | + PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; __ Test(Operand(elements, scratch1, times_pointer_size, @@ -720,7 +720,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, // Probe the stub cache. Code::Flags flags = Code::ComputeFlags(kind, - NOT_IN_LOOP, MONOMORPHIC, extra_ic_state, NORMAL, @@ -1267,9 +1266,7 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // ----------------------------------- // Probe the stub cache. - Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, - NOT_IN_LOOP, - MONOMORPHIC); + Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC); Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rax, rcx, rbx, rdx); @@ -1372,10 +1369,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm, // ----------------------------------- // Get the receiver from the stack and probe the stub cache. - Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, - NOT_IN_LOOP, - MONOMORPHIC, - strict_mode); + Code::Flags flags = + Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode); Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg); diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc index bedf1be437..9064a266e7 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.cc +++ b/deps/v8/src/x64/lithium-codegen-x64.cc @@ -100,7 +100,8 @@ void LCodeGen::FinishCode(Handle<Code> code) { void LCodeGen::Abort(const char* format, ...) { if (FLAG_trace_bailout) { - SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + SmartArrayPointer<char> name( + info()->shared_info()->DebugName()->ToCString()); PrintF("Aborting LCodeGen in @\"%s\": ", *name); va_list arguments; va_start(arguments, format); @@ -2219,11 +2220,11 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) { __ movzxbq(temp, FieldOperand(temp, Map::kBitField2Offset)); __ and_(temp, Immediate(Map::kElementsKindMask)); __ shr(temp, Immediate(Map::kElementsKindShift)); - __ cmpl(temp, Immediate(JSObject::FAST_ELEMENTS)); + __ cmpl(temp, Immediate(FAST_ELEMENTS)); __ j(equal, &ok, Label::kNear); - __ cmpl(temp, Immediate(JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); + __ cmpl(temp, Immediate(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); __ j(less, &fail, Label::kNear); - __ cmpl(temp, Immediate(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); + __ cmpl(temp, Immediate(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); __ j(less_equal, &ok, Label::kNear); __ bind(&fail); __ Abort("Check for fast or external elements failed"); @@ -2267,7 +2268,7 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { // Load the result. __ movq(result, BuildFastArrayOperand(instr->elements(), instr->key(), - JSObject::FAST_ELEMENTS, + FAST_ELEMENTS, FixedArray::kHeaderSize - kHeapObjectTag)); // Check for the hole value. @@ -2288,14 +2289,14 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( Operand hole_check_operand = BuildFastArrayOperand( instr->elements(), instr->key(), - JSObject::FAST_DOUBLE_ELEMENTS, + FAST_DOUBLE_ELEMENTS, offset); __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); DeoptimizeIf(equal, instr->environment()); } Operand double_load_operand = BuildFastArrayOperand( - instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, + instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, FixedDoubleArray::kHeaderSize - kHeapObjectTag); __ movsd(result, double_load_operand); } @@ -2304,7 +2305,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( Operand LCodeGen::BuildFastArrayOperand( LOperand* elements_pointer, LOperand* key, - JSObject::ElementsKind elements_kind, + ElementsKind elements_kind, uint32_t offset) { Register elements_pointer_reg = ToRegister(elements_pointer); int shift_size = ElementsKindToShiftSize(elements_kind); @@ -2325,35 +2326,35 @@ Operand LCodeGen::BuildFastArrayOperand( void LCodeGen::DoLoadKeyedSpecializedArrayElement( LLoadKeyedSpecializedArrayElement* instr) { - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildFastArrayOperand(instr->external_pointer(), instr->key(), elements_kind, 0)); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { XMMRegister result(ToDoubleRegister(instr->result())); __ movss(result, operand); __ cvtss2sd(result, result); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ movsd(ToDoubleRegister(instr->result()), operand); } else { Register result(ToRegister(instr->result())); switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ movsxbq(result, operand); break; - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: __ movzxbq(result, operand); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: __ movsxwq(result, operand); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzxwq(result, operand); break; - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: __ movsxlq(result, operand); break; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(result, operand); __ testl(result, result); // TODO(danno): we could be more clever here, perhaps having a special @@ -2361,12 +2362,12 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( // happens, and generate code that returns a double rather than int. DeoptimizeIf(negative, instr->environment()); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -2952,8 +2953,8 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) { ASSERT(ToRegister(instr->result()).is(rax)); int arity = instr->arity(); - Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( - arity, NOT_IN_LOOP); + Handle<Code> ic = + isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); CallCode(ic, RelocInfo::CODE_TARGET, instr); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); } @@ -2965,7 +2966,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { int arity = instr->arity(); RelocInfo::Mode mode = RelocInfo::CODE_TARGET; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); + isolate()->stub_cache()->ComputeCallInitialize(arity, mode); __ Move(rcx, instr->name()); CallCode(ic, mode, instr); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); @@ -2976,7 +2977,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { ASSERT(ToRegister(instr->result()).is(rax)); int arity = instr->arity(); - CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); + CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); __ Drop(1); @@ -2988,7 +2989,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { int arity = instr->arity(); RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; Handle<Code> ic = - isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); + isolate()->stub_cache()->ComputeCallInitialize(arity, mode); __ Move(rcx, instr->name()); CallCode(ic, mode, instr); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); @@ -3061,37 +3062,37 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { void LCodeGen::DoStoreKeyedSpecializedArrayElement( LStoreKeyedSpecializedArrayElement* instr) { - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); Operand operand(BuildFastArrayOperand(instr->external_pointer(), instr->key(), elements_kind, 0)); - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { XMMRegister value(ToDoubleRegister(instr->value())); __ cvtsd2ss(value, value); __ movss(operand, value); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ movsd(operand, ToDoubleRegister(instr->value())); } else { Register value(ToRegister(instr->value())); switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movb(operand, value); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movw(operand, value); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(operand, value); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } @@ -3164,7 +3165,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( __ bind(&have_value); Operand double_store_operand = BuildFastArrayOperand( - instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, + instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, FixedDoubleArray::kHeaderSize - kHeapObjectTag); __ movsd(double_store_operand, value); } diff --git a/deps/v8/src/x64/lithium-codegen-x64.h b/deps/v8/src/x64/lithium-codegen-x64.h index 0622e9d285..8cb4cece96 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.h +++ b/deps/v8/src/x64/lithium-codegen-x64.h @@ -218,7 +218,7 @@ class LCodeGen BASE_EMBEDDED { Operand BuildFastArrayOperand( LOperand* elements_pointer, LOperand* key, - JSObject::ElementsKind elements_kind, + ElementsKind elements_kind, uint32_t offset); // Specific math operations - used from DoUnaryMathOperation. diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc index bd319560cb..5fc56462bb 100644 --- a/deps/v8/src/x64/lithium-x64.cc +++ b/deps/v8/src/x64/lithium-x64.cc @@ -313,13 +313,13 @@ void LCallKeyed::PrintDataTo(StringStream* stream) { void LCallNamed::PrintDataTo(StringStream* stream) { - SmartPointer<char> name_string = name()->ToCString(); + SmartArrayPointer<char> name_string = name()->ToCString(); stream->Add("%s #%d / ", *name_string, arity()); } void LCallGlobal::PrintDataTo(StringStream* stream) { - SmartPointer<char> name_string = name()->ToCString(); + SmartArrayPointer<char> name_string = name()->ToCString(); stream->Add("%s #%d / ", *name_string, arity()); } @@ -539,7 +539,8 @@ LChunk* LChunkBuilder::Build() { void LChunkBuilder::Abort(const char* format, ...) { if (FLAG_trace_bailout) { - SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); + SmartArrayPointer<char> name( + info()->shared_info()->DebugName()->ToCString()); PrintF("Aborting LChunk building in @\"%s\": ", *name); va_list arguments; va_start(arguments, format); @@ -1840,15 +1841,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( HLoadKeyedSpecializedArrayElement* instr) { - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); Representation representation(instr->representation()); ASSERT( (representation.IsInteger32() && - (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (representation.IsDouble() && - ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); + ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* key = UseRegisterOrConstant(instr->key()); @@ -1857,7 +1858,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* load_instr = DefineAsRegister(result); // An unsigned int array load might overflow and cause a deopt, make sure it // has an environment. - return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ? + return (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) ? AssignEnvironment(load_instr) : load_instr; } @@ -1907,21 +1908,21 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( HStoreKeyedSpecializedArrayElement* instr) { Representation representation(instr->value()->representation()); - JSObject::ElementsKind elements_kind = instr->elements_kind(); + ElementsKind elements_kind = instr->elements_kind(); ASSERT( (representation.IsInteger32() && - (elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || + (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && + (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (representation.IsDouble() && - ((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); + ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || + (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->key()->representation().IsInteger32()); LOperand* external_pointer = UseRegister(instr->external_pointer()); bool val_is_temp_register = - elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS || - elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS; + elements_kind == EXTERNAL_PIXEL_ELEMENTS || + elements_kind == EXTERNAL_FLOAT_ELEMENTS; LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) : UseRegister(instr->value()); diff --git a/deps/v8/src/x64/lithium-x64.h b/deps/v8/src/x64/lithium-x64.h index b570672f68..d169bf6dfc 100644 --- a/deps/v8/src/x64/lithium-x64.h +++ b/deps/v8/src/x64/lithium-x64.h @@ -1155,7 +1155,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } - JSObject::ElementsKind elements_kind() const { + ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } }; @@ -1631,7 +1631,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> { LOperand* external_pointer() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - JSObject::ElementsKind elements_kind() const { + ElementsKind elements_kind() const { return hydrogen()->elements_kind(); } }; diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc index 2ee506d7c3..9cfc9b6588 100644 --- a/deps/v8/src/x64/macro-assembler-x64.cc +++ b/deps/v8/src/x64/macro-assembler-x64.cc @@ -2415,7 +2415,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location, } // Save the current handler. Operand handler_operand = - ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); + ExternalOperand(ExternalReference(Isolate::kHandlerAddress, isolate())); push(handler_operand); // Link this handler. movq(handler_operand, rsp); @@ -2426,7 +2426,7 @@ void MacroAssembler::PopTryHandler() { ASSERT_EQ(0, StackHandlerConstants::kNextOffset); // Unlink this handler. Operand handler_operand = - ExternalOperand(ExternalReference(Isolate::k_handler_address, isolate())); + ExternalOperand(ExternalReference(Isolate::kHandlerAddress, isolate())); pop(handler_operand); // Remove the remaining fields. addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); @@ -2446,7 +2446,7 @@ void MacroAssembler::Throw(Register value) { movq(rax, value); } - ExternalReference handler_address(Isolate::k_handler_address, isolate()); + ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); Operand handler_operand = ExternalOperand(handler_address); movq(rsp, handler_operand); // get next in chain @@ -2482,7 +2482,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, movq(rax, value); } // Fetch top stack handler. - ExternalReference handler_address(Isolate::k_handler_address, isolate()); + ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); Load(rsp, handler_address); // Unwind the handlers until the ENTRY handler is found. @@ -2505,12 +2505,12 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, if (type == OUT_OF_MEMORY) { // Set external caught exception to false. ExternalReference external_caught( - Isolate::k_external_caught_exception_address, isolate()); + Isolate::kExternalCaughtExceptionAddress, isolate()); Set(rax, static_cast<int64_t>(false)); Store(external_caught, rax); // Set pending exception and rax to out of memory exception. - ExternalReference pending_exception(Isolate::k_pending_exception_address, + ExternalReference pending_exception(Isolate::kPendingExceptionAddress, isolate()); movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE); Store(pending_exception, rax); @@ -2567,7 +2567,7 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { void MacroAssembler::CheckFastElements(Register map, Label* fail, Label::Distance distance) { - STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); + STATIC_ASSERT(FAST_ELEMENTS == 0); cmpb(FieldOperand(map, Map::kBitField2Offset), Immediate(Map::kMaximumBitField2FastElementValue)); j(above, fail, distance); @@ -3041,8 +3041,8 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax) { movq(r14, rax); // Backup rax in callee-save register. } - Store(ExternalReference(Isolate::k_c_entry_fp_address, isolate()), rbp); - Store(ExternalReference(Isolate::k_context_address, isolate()), rsi); + Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); + Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); } @@ -3132,7 +3132,7 @@ void MacroAssembler::LeaveApiExitFrame() { void MacroAssembler::LeaveExitFrameEpilogue() { // Restore current context from top and clear it in debug mode. - ExternalReference context_address(Isolate::k_context_address, isolate()); + ExternalReference context_address(Isolate::kContextAddress, isolate()); Operand context_operand = ExternalOperand(context_address); movq(rsi, context_operand); #ifdef DEBUG @@ -3140,7 +3140,7 @@ void MacroAssembler::LeaveExitFrameEpilogue() { #endif // Clear the top frame. - ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, + ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); movq(c_entry_fp_operand, Immediate(0)); @@ -3303,7 +3303,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss, NumberDictionary::kElementsStartOffset + 2 * kPointerSize; ASSERT_EQ(NORMAL, 0); Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), - Smi::FromInt(PropertyDetails::TypeField::mask())); + Smi::FromInt(PropertyDetails::TypeField::kMask)); j(not_zero, miss); // Get the value at the masked, scaled index. diff --git a/deps/v8/src/x64/stub-cache-x64.cc b/deps/v8/src/x64/stub-cache-x64.cc index 5ea72579b4..76d2555798 100644 --- a/deps/v8/src/x64/stub-cache-x64.cc +++ b/deps/v8/src/x64/stub-cache-x64.cc @@ -2537,7 +2537,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { // -- rsp[0] : return address // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; MaybeObject* maybe_stub = KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); @@ -2996,7 +2996,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { // -- rsp[0] : return address // ----------------------------------- Code* stub; - JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); + ElementsKind elements_kind = receiver_map->elements_kind(); MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); if (!maybe_stub->To(&stub)) return maybe_stub; __ DispatchMap(rdx, @@ -3227,7 +3227,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- rax : key // -- rdx : receiver @@ -3255,29 +3255,29 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); // rbx: base pointer of external storage switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: __ movsxbq(rcx, Operand(rbx, rcx, times_1, 0)); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movzxbq(rcx, Operand(rbx, rcx, times_1, 0)); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0)); break; - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0)); break; - case JSObject::EXTERNAL_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0)); break; - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(rcx, Operand(rbx, rcx, times_4, 0)); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0)); break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: __ movsd(xmm0, Operand(rbx, rcx, times_8, 0)); break; default: @@ -3293,7 +3293,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // xmm0: value as double. ASSERT(kSmiValueSize == 32); - if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { + if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { // For the UnsignedInt array type, we need to see whether // the value can be represented in a Smi. If not, we need to convert // it to a HeapNumber. @@ -3317,8 +3317,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); __ movq(rax, rcx); __ ret(0); - } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || - elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || + elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. __ AllocateHeapNumber(rcx, rbx, &slow); @@ -3361,7 +3361,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, - JSObject::ElementsKind elements_kind) { + ElementsKind elements_kind) { // ----------- S t a t e ------------- // -- rax : value // -- rcx : key @@ -3391,7 +3391,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // rbx: elements array // rdi: untagged key Label check_heap_number; - if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { // Float to pixel conversion is only implemented in the runtime for now. __ JumpIfNotSmi(rax, &slow); } else { @@ -3402,7 +3402,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset)); // rbx: base pointer of external storage switch (elements_kind) { - case JSObject::EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: { // Clamp the value to [0..255]. Label done; __ testl(rdx, Immediate(0xFFFFFF00)); @@ -3413,39 +3413,39 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( } __ movb(Operand(rbx, rdi, times_1, 0), rdx); break; - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ movb(Operand(rbx, rdi, times_1, 0), rdx); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ movw(Operand(rbx, rdi, times_2, 0), rdx); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ movl(Operand(rbx, rdi, times_4, 0), rdx); break; - case JSObject::EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: // Need to perform int-to-float conversion. __ cvtlsi2ss(xmm0, rdx); __ movss(Operand(rbx, rdi, times_4, 0), xmm0); break; - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: // Need to perform int-to-float conversion. __ cvtlsi2sd(xmm0, rdx); __ movsd(Operand(rbx, rdi, times_8, 0), xmm0); break; - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } __ ret(0); // TODO(danno): handle heap number -> pixel array conversion - if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { + if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { __ bind(&check_heap_number); // rax: value // rcx: key (a smi) @@ -3464,11 +3464,11 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // rdi: untagged index // rbx: base pointer of external storage // top of FPU stack: value - if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ cvtsd2ss(xmm0, xmm0); __ movss(Operand(rbx, rdi, times_4, 0), xmm0); __ ret(0); - } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { __ movsd(Operand(rbx, rdi, times_8, 0), xmm0); __ ret(0); } else { @@ -3482,30 +3482,30 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // rdi: untagged index // rbx: base pointer of external storage switch (elements_kind) { - case JSObject::EXTERNAL_BYTE_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: + case EXTERNAL_BYTE_ELEMENTS: + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ cvttsd2si(rdx, xmm0); __ movb(Operand(rbx, rdi, times_1, 0), rdx); break; - case JSObject::EXTERNAL_SHORT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: + case EXTERNAL_SHORT_ELEMENTS: + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ cvttsd2si(rdx, xmm0); __ movw(Operand(rbx, rdi, times_2, 0), rdx); break; - case JSObject::EXTERNAL_INT_ELEMENTS: - case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: + case EXTERNAL_INT_ELEMENTS: + case EXTERNAL_UNSIGNED_INT_ELEMENTS: // Convert to int64, so that NaN and infinities become // 0x8000000000000000, which is zero mod 2^32. __ cvttsd2siq(rdx, xmm0); __ movl(Operand(rbx, rdi, times_4, 0), rdx); break; - case JSObject::EXTERNAL_PIXEL_ELEMENTS: - case JSObject::EXTERNAL_FLOAT_ELEMENTS: - case JSObject::EXTERNAL_DOUBLE_ELEMENTS: - case JSObject::FAST_ELEMENTS: - case JSObject::FAST_DOUBLE_ELEMENTS: - case JSObject::DICTIONARY_ELEMENTS: - case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: + case EXTERNAL_PIXEL_ELEMENTS: + case EXTERNAL_FLOAT_ELEMENTS: + case EXTERNAL_DOUBLE_ELEMENTS: + case FAST_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: + case DICTIONARY_ELEMENTS: + case NON_STRICT_ARGUMENTS_ELEMENTS: UNREACHABLE(); break; } diff --git a/deps/v8/src/zone-inl.h b/deps/v8/src/zone-inl.h index 6e2d558a60..4870105f31 100644 --- a/deps/v8/src/zone-inl.h +++ b/deps/v8/src/zone-inl.h @@ -55,7 +55,12 @@ inline void* Zone::New(int size) { // Check if the requested size is available without expanding. Address result = position_; - if ((position_ += size) > limit_) result = NewExpand(size); + + if (size > limit_ - position_) { + result = NewExpand(size); + } else { + position_ += size; + } // Check that the result has the proper alignment and return it. ASSERT(IsAddressAligned(result, kAlignment, 0)); diff --git a/deps/v8/src/zone.cc b/deps/v8/src/zone.cc index 7574778f53..2d14d137ef 100644 --- a/deps/v8/src/zone.cc +++ b/deps/v8/src/zone.cc @@ -168,7 +168,7 @@ Address Zone::NewExpand(int size) { // Make sure the requested size is already properly aligned and that // there isn't enough room in the Zone to satisfy the request. ASSERT(size == RoundDown(size, kAlignment)); - ASSERT(position_ + size > limit_); + ASSERT(size > limit_ - position_); // Compute the new segment size. We use a 'high water mark' // strategy, where we increase the segment size every time we expand @@ -177,7 +177,13 @@ Address Zone::NewExpand(int size) { Segment* head = segment_head_; int old_size = (head == NULL) ? 0 : head->size(); static const int kSegmentOverhead = sizeof(Segment) + kAlignment; - int new_size = kSegmentOverhead + size + (old_size << 1); + int new_size_no_overhead = size + (old_size << 1); + int new_size = kSegmentOverhead + new_size_no_overhead; + // Guard against integer overflow. + if (new_size_no_overhead < size || new_size < kSegmentOverhead) { + V8::FatalProcessOutOfMemory("Zone"); + return NULL; + } if (new_size < kMinimumSegmentSize) { new_size = kMinimumSegmentSize; } else if (new_size > kMaximumSegmentSize) { @@ -196,6 +202,11 @@ Address Zone::NewExpand(int size) { // Recompute 'top' and 'limit' based on the new segment. Address result = RoundUp(segment->start(), kAlignment); position_ = result + size; + // Check for address overflow. + if (position_ < result) { + V8::FatalProcessOutOfMemory("Zone"); + return NULL; + } limit_ = segment->end(); ASSERT(position_ <= limit_); return result; |