Revision: 23275
Author: [email protected]
Date: Thu Aug 21 12:40:10 2014 UTC
Log: Reland "Load global object and builtins from activation."
Reland fixes:
Don't set string flags (doing so leaks memory).
Load closure from activation for building literals.
[email protected]
Review URL: https://codereview.chromium.org/484273003
http://code.google.com/p/v8/source/detail?r=23275
Modified:
/branches/bleeding_edge/src/compiler/ast-graph-builder.cc
/branches/bleeding_edge/src/compiler/ast-graph-builder.h
/branches/bleeding_edge/src/compiler/pipeline.cc
/branches/bleeding_edge/src/compiler/pipeline.h
/branches/bleeding_edge/test/cctest/compiler/function-tester.h
/branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc
=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Thu Aug 21
11:56:46 2014 UTC
+++ /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Thu Aug 21
12:40:10 2014 UTC
@@ -6,6 +6,7 @@
#include "src/compiler.h"
#include "src/compiler/control-builders.h"
+#include "src/compiler/machine-operator.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node-properties-inl.h"
#include "src/full-codegen.h"
@@ -701,13 +702,12 @@
test_should_filter.If(should_filter_cond);
test_should_filter.Then();
value = environment()->Pop();
- // TODO(dcarney): Better load from function context.
- // See comment in BuildLoadBuiltinsObject.
- Handle<JSFunction> function(JSFunction::cast(
- info()->context()->builtins()->javascript_builtin(
- Builtins::FILTER_KEY)));
+ Node* builtins = BuildLoadBuiltinsObject();
+ Node* function = BuildLoadObjectField(
+ builtins,
+
JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
// Callee.
- environment()->Push(jsgraph()->HeapConstant(function));
+ environment()->Push(function);
// Receiver.
environment()->Push(obj);
// Args.
@@ -840,10 +840,11 @@
void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
- Handle<JSFunction> closure = info()->closure();
+ Node* closure = GetFunctionClosure();
// Create node to materialize a regular expression literal.
- Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+ Node* literals_array =
+ BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
Node* literal_index = jsgraph()->Constant(expr->literal_index());
Node* pattern = jsgraph()->Constant(expr->pattern());
Node* flags = jsgraph()->Constant(expr->flags());
@@ -854,11 +855,12 @@
void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
- Handle<JSFunction> closure = info()->closure();
+ Node* closure = GetFunctionClosure();
// Create node to deep-copy the literal boilerplate.
expr->BuildConstantProperties(isolate());
- Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+ Node* literals_array =
+ BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
Node* literal_index = jsgraph()->Constant(expr->literal_index());
Node* constants = jsgraph()->Constant(expr->constant_properties());
Node* flags = jsgraph()->Constant(expr->ComputeFlags());
@@ -963,11 +965,12 @@
void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
- Handle<JSFunction> closure = info()->closure();
+ Node* closure = GetFunctionClosure();
// Create node to deep-copy the literal boilerplate.
expr->BuildConstantElements(isolate());
- Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+ Node* literals_array =
+ BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
Node* literal_index = jsgraph()->Constant(expr->literal_index());
Node* constants = jsgraph()->Constant(expr->constant_elements());
Node* flags = jsgraph()->Constant(expr->ComputeFlags());
@@ -1906,27 +1909,30 @@
UNREACHABLE();
return NULL;
}
+
+
+Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
+ // TODO(sigurds) Use simplified load here once it is ready.
+ MachineOperatorBuilder machine(zone());
+ Node* field_load = NewNode(machine.Load(kMachAnyTagged), object,
+ jsgraph_->Int32Constant(offset -
kHeapObjectTag));
+ return field_load;
+}
Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
- // TODO(mstarzinger): Better load from function context, otherwise
optimized
- // code cannot be shared across native contexts.
- return jsgraph()->Constant(handle(info()->context()->builtins()));
+ Node* global = BuildLoadGlobalObject();
+ Node* builtins =
+ BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
+ return builtins;
}
Node* AstGraphBuilder::BuildLoadGlobalObject() {
-#if 0
Node* context = GetFunctionContext();
- // TODO(mstarzinger): Use mid-level operator on FixedArray instead of the
- // JS-level operator that targets JSObject.
- Node* index = jsgraph()->Constant(Context::GLOBAL_OBJECT_INDEX);
- return NewNode(javascript()->LoadProperty(), context, index);
-#else
- // TODO(mstarzinger): Better load from function context, otherwise
optimized
- // code cannot be shared across native contexts. See unused code above.
- return jsgraph()->Constant(handle(info()->context()->global_object()));
-#endif
+ Operator* load_op =
+ javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
+ return NewNode(load_op, context);
}
=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.h Thu Aug 21
11:56:46 2014 UTC
+++ /branches/bleeding_edge/src/compiler/ast-graph-builder.h Thu Aug 21
12:40:10 2014 UTC
@@ -88,6 +88,7 @@
Node* BuildLoadBuiltinsObject();
Node* BuildLoadGlobalObject();
Node* BuildLoadClosure();
+ Node* BuildLoadObjectField(Node* object, int offset);
// Builders for automatic type conversion.
Node* BuildToBoolean(Node* value);
=======================================
--- /branches/bleeding_edge/src/compiler/pipeline.cc Wed Aug 20 13:05:03
2014 UTC
+++ /branches/bleeding_edge/src/compiler/pipeline.cc Thu Aug 21 12:40:10
2014 UTC
@@ -186,7 +186,7 @@
VerifyAndPrintGraph(&graph, "Initial untyped");
- if (FLAG_context_specialization) {
+ if (context_specialization_) {
SourcePositionTable::Scope pos(&source_positions,
SourcePosition::Unknown());
// Specialize the code to the context as aggressively as possible.
=======================================
--- /branches/bleeding_edge/src/compiler/pipeline.h Wed Aug 13 14:05:37
2014 UTC
+++ /branches/bleeding_edge/src/compiler/pipeline.h Thu Aug 21 12:40:10
2014 UTC
@@ -24,7 +24,8 @@
class Pipeline {
public:
- explicit Pipeline(CompilationInfo* info) : info_(info) {}
+ explicit Pipeline(CompilationInfo* info)
+ : info_(info), context_specialization_(FLAG_context_specialization)
{}
// Run the entire pipeline and generate a handle to a code object.
Handle<Code> GenerateCode();
@@ -39,9 +40,14 @@
static void SetUp();
static void TearDown();
+ bool context_specialization() { return context_specialization_; }
+ void set_context_specialization(bool context_specialization) {
+ context_specialization_ = context_specialization;
+ }
private:
CompilationInfo* info_;
+ bool context_specialization_;
CompilationInfo* info() const { return info_; }
Isolate* isolate() { return info_->isolate(); }
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/function-tester.h Tue Aug
19 11:24:24 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/function-tester.h Thu Aug
21 12:40:10 2014 UTC
@@ -26,10 +26,13 @@
class FunctionTester : public InitializedHandleScope {
public:
- explicit FunctionTester(const char* source)
+ explicit FunctionTester(const char* source, bool context_specialization =
+
FLAG_context_specialization)
: isolate(main_isolate()),
- function((FLAG_allow_natives_syntax = true, NewFunction(source))) {
+ function((FLAG_allow_natives_syntax = true, NewFunction(source))),
+ context_specialization_(context_specialization) {
Compile(function);
+ USE(context_specialization_);
}
Isolate* isolate;
@@ -52,6 +55,7 @@
EnsureDeoptimizationSupport(&info);
Pipeline pipeline(&info);
+ pipeline.set_context_specialization(context_specialization_);
Handle<Code> code = pipeline.GenerateCode();
CHECK(!code.is_null());
@@ -188,6 +192,9 @@
Handle<Object> true_value() { return isolate->factory()->true_value(); }
Handle<Object> false_value() { return isolate->factory()->false_value();
}
+
+ private:
+ bool context_specialization_;
};
}
}
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc Tue
Aug 19 16:07:15 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc Thu
Aug 21 12:40:10 2014 UTC
@@ -245,3 +245,45 @@
T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
}
+
+
+TEST(ContextLoadedFromActivation) {
+ const char* script =
+ "var x = 42;"
+ "(function() {"
+ " return function () { return x };"
+ "})()";
+
+ // Disable context specialization.
+ FunctionTester T(script, false);
+ v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
+ v8::Context::Scope scope(context);
+ v8::Local<v8::Value> value = CompileRun(script);
+ i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
+ i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
+ jsfun->set_code(T.function->code());
+ context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
+ CompileRun("var x = 24;");
+ ExpectInt32("foo();", 24);
+}
+
+
+TEST(BuiltinLoadedFromActivation) {
+ const char* script =
+ "var x = 42;"
+ "(function() {"
+ " return function () { return this; };"
+ "})()";
+
+ // Disable context specialization.
+ FunctionTester T(script, false);
+ v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
+ v8::Context::Scope scope(context);
+ v8::Local<v8::Value> value = CompileRun(script);
+ i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
+ i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
+ jsfun->set_code(T.function->code());
+ context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
+ CompileRun("var x = 24;");
+ ExpectObject("foo()", context->Global());
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.